Pinia是vue团队推荐的下一代状态管理方案,相比之前的vuex方案,Pinia具有以下特点:
npm i pinia -S
接着src目录下创建stores文件夹(注意:这里用复数形式命名以强调pinia的多状态实例的特性,也就是上面提到的特点3)
stores文件夹下新建index.ts:
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia
import { createSSRApp } from 'vue'
import App from './App.vue'
import pinia from './store'
export function createApp() {
const app = createSSRApp(App)
app.use(pinia)
return {
app,
}
}
以上就完成了初始化工作,下面我们定义一个user模块说明如何使用
在stores目录下新建user文件夹,在其目录下我们新建两个文件:index.ts和types.ts(管理数据结构)
index.ts:
import { defineStore } from 'pinia'
import { RootState } from './types'
export const useUserStore = defineStore('user', {
state: (): RootState => ({
userInfo: {},
token: '',
}),
getters: {
// 示例返回大写字符
capName(state) {
return state.userInfo.name.toUpperCase()
},
},
actions: {
async setUserInfo() {
// 这里可以发起请求
const userInfo = await getUserInfo()
this.userInfo = userInfo
},
},
})
值得一提的是,对于store模块命名写法,有个约定俗成的写法:使用“use”+ 功能模块名称,如上面的useUserStore
<template>
<view>{userStore.userInfo.name}</view>
</template>
<script setup lang="ts">
import { useUserStore } from '@/stores/user'
const userStore = useUserStore()
console.log(userStore.userInfo)
</script>
如果要使用解构写法获取值,而又不丢失响应式,我们需要用到storeToRefs方法
const { userInfo } = storeToRefs(userStore)
userInfo.value.name = 'username'
// $patch有两种写法
// 传入对象:适合同时修改多个不复杂的数据
store.$patch({
userInfo: {},
token: '',
})
// 传入函数写法:上面传入对象写法在遇到复杂数据时,成本很高
//(例如,从数组中推送、删除、拼接元素)都需要创建一个新集合,这时就可以传入一个函数
cartStore.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 })
state.hasChanged = true
})
userInfo: {
name: '默认用户名',
avatar: '默认用户头像'
}
假设用户登录后我们修改了上面的用户信息,退出登录时,我们可以直接调用userStore.$reset()恢复初始值。不过要注意的是,它恢复的是整个state值,并不能只恢复state下面的单个值。对此,我们可以将有恢复初始值的需求的变量,用一个变量存储然后在需要恢复时,可以在action中定义一个方法重新赋值即可。
如果你需要监听状态做一些处理,例如将数据持久化到本地,可以使用$subscribe()方法。
userStore.$subscribe((mutations, state) => {
uni.setStorageSync('userInfo', state.userInfo)
})
在只需要本地存储一小部分字段时,可以通过上面监听状态钩子简易实现。但如果需要存储大量数据字段,则可以使用与之搭配的插件:pinia-plugin-persistedstate
npm i pinia-plugin-persistedstate
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
export default pinia
export const useUserStore = defineStore('user', {
state: (): RootState => ({
userInfo: {
id: null,
name: '',
},
token: '',
userName: '',
}),
persist: {
key: 'store-key', // 本地存储key
storage: {
setItem: uni.setStorageSync,
getItem: uni.getStorageSync,
},
},
actions: {
setName(name: string) {
this.userName = name
},
},
})
打开微信开发者工具可以看到:
可以看到上面存储的是整个user模块的state数据,如果只需要存储state下的某些字段,可以这么写:
persist: {
key: 'store-key',
paths: ['userInfo.name'],
storage: {
setItem: uni.setStorageSync,
getItem: uni.getStorageSync,
},
}
微信开发工具中显示如下:
至此,已经完成了pinia状态管理使用及配合pinia-plugin-persistedstate插件实现数据本地存储,接下来请移步《网络请求封装篇》。
阅读量:2028
点赞量:0
收藏量:0