vue3如何用pinia替代vuex
作者:sqwu
这篇文章主要介绍了vue3如何使用pinia替代vuex问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
pinia是vue团队推荐代替vuex的一款轻量级状态管理库。
1. 安装
npm i pinia --save
2. pinia特点
- 完整的typescript支持
- 足够轻量,压缩后的体积只有1.6kb
- 去除mutations,只保留state,getters,actions
- actions同时支持同步和异步
- 没有modules模块的概念,只有store,store之间可以互相引用,更好的代码分割
3. 使用
1.初始化store
创建目录store/index.ts
import { createPinia } from 'pinia'
const store = createPinia()
export default store
2.在main.ts引用store
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
const app = createApp(App)
app.use(store)
app.mount('#app')
3.创建store
根据功能模块在store下创建ts文件,维护各个功能的数据,如用户模块user.ts,维护两个字段:userInfo和token,通过actions里面的方法修改userInfo和token的内容
import { defineStore } from 'pinia'
interface UserInfo {
name?: string
age?: number
}
// 第一个参数是id,id必填,且需要保证值唯一
export const useUserStore = defineStore('user', {
state: (): {
userInfo: UserInfo
token: string
} => {
return {
userInfo: {},
token: ''
}
},
getters: {
newName: state => state.userInfo.name + '牛'
},
actions: {
updateUserInfo(userInfo: UserInfo) {
this.userInfo = userInfo
},
updateToken(token: string) {
this.token = token
}
}
})
4.读取数据
引入要读取的store
<script setup lang="ts">
import { useUserStore } from '../../store/user'
const userStore = useUserStore()
// 读取state中的数据
const userInfo: ComputedRef<{
name?: string
age?: number
}> = computed(() => userStore.userInfo)
// 读取getter中的数据
const newName = userStore.newName
</script>
5.修改数据
<script lang="ts" setup>
import { useUserStore } from '../../store/user'
const userStore = useUserStore()
function handleLogin() {
userStore.updateUserInfo({ name: '李二' })
}
</script>
6.store的相互引用
不同store之间引用,举个🌰:创建user2.ts,引用user.ts的数据
import { defineStore } from 'pinia'
import { useUserStore } from './user'
export const useUser2Store = defineStore('user2', {
state: (): {
sex: string
} => {
return {
sex: '0'
}
},
actions: {
sayInfo(sex: string) {
this.sex = sex
// 引用其他store
const userStore = useUserStore()
console.log(
`我叫${userStore.newName}, 我是个小${
this.sex === '0' ? '姑娘' : '伙子'
}`
)
}
}
})
在组件中使用user2模块
<script lang="ts" setup>
import { useUser2Store } from '../../store/user2'
const user2Store = useUser2Store()
setTimeout(() => {
user2Store.sayInfo('1')
}, 3000) // 3s后输出----》 我叫李二牛, 我是个小伙子
</script>
7.devtools
在devtools中可以看到,pinia会自动根据文件区分模块!

4.数据持久化
开启持久化可以在页面刷新的时候,帮我们把数据缓存下来,不被清空。
1.安装插件
npm i pinia-plugin-persist --save
2.引用插件
在store/index.ts引入插件,并且use
import { createPinia } from 'pinia'
import piniaPluginpersist from 'pinia-plugin-persist'
const store = createPinia()
// 使用持久化插件
store.use(piniaPluginpersist)
export default store
3.在store模块中启用持久化
(1) 启用
在user.ts中启用:添加persist配置项
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: (): {
userInfo: UserInfo
token: string
} => ({
userInfo: {},
token: ''
}),
getters: { ... },
actions: { ... },
// 开始数据持久化
persist: {
enabled: true
}
})
数据会默认存储到sessionStorage,可以在控制台看到。

(2) 修改key & 存储位置
默认存储到sessionStorage的key值就是store模块id值。可以通过strategies修改key值和存储位置,如:
将key值改为_user,存储位置改为localStorage(注意之前缓存在sessionStorage中的数据还在,可以手动清除一下sessionStorage.clear())
persist: {
enabled: true,
strategies: [{
key: '_user',
storage: localStorage
}]
}
在控制台打印localStorage

(3) 自定义要持久化的字段
默认会将store中的所有字段都缓存,可以通过paths指定要缓存的字段。
如:我只要缓存userInfo
persist: {
enabled: true,
strategies: [{
key: '_user',
storage: localStorage,
paths: ['userInfo']
}]
}
控制台打印,可以看到token字段没有了!

总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
