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字段没有了!
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。