/*
Pinia
没有 Mutations
State
Getters
Actions 异步
1 安装
npm i pinia
2 使用
/store--index
import { createPinia } from 'pinia'
const pinia = createPinia()
export default pinia
main.js
// 引入pinia
import pinia from './stores'
app.use( pinia )
// uniapp 引入 pinia
// main.js
// #ifdef VUE3
import {
createSSRApp
} from 'vue'
// 引入 pinia
import pinia from './store'
export function createApp() {
const app = createSSRApp(App)
app.use(pinia)
return {
app
}
}
// #endif
/store/modules/mainStore.js 文件夹
import { defineStore } from 'pinia'
export const useMainStore = defineStore('main',{
// 必须是 箭头函数 -- TS 类型推导
state:()=>{
return {
count:100,
foo:'bar',
arr:[1,2,3]
}
}
actions:{
changeState(){
// this
this.count ++
// 批量 $patch
this.$patch(state=>state.foo="hello")
},
changeState2(m){
// this
this.count ++
// 批量 $patch
this.$patch(state=>state.foo="hello")
}
},
getters:{
count10(state){
return state.count + 10
},
// TS 中 没有参数 state 无法推断返回值类型 需要手动 指定 :number
count20(){
return this.count + 20
}
// 调用 其他 getter
count21(){
return this.count20 + 20
}
// 接收参数 函数返回值 是一个函数 所以 组件中 调用 count22(100) 实际调用的是 箭头函数 m为100
count22(state){
return m =>state.count + m
}
}
})
定义store模式有2种:options API 和 composition API
上面 就是 options API 配置项
// 使用composition API模式定义store setup 写法
export const useCounterStoreForSetup = defineStore('counterForSetup', () => {
const count = ref<number>(1)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, increment }
})
composition API中的ref、reactive定义的变量等价于options API中的state;
composition API中的computed属性等价于options API中的getters;
composition API中的导出函数等价于options API中的actions;
组件中
import { useMainStore } from '@/store'
// mainStore 为 reactive 对象
const mainStore = useMainStore()
const count = mainStore.count
// 解构 不是响应式的
const { count } = mainStore
// 解决方案 storeToRefs
import { storeToRefs } from 'pinia'
const { count } = storeToRefs(mainStore)
// count 为 ref 了 count.value
修改数据
1 直接修改
mainStore.count ++
2 批量修改 有性能优化 $patch 对象方式
mainStore.$patch({
count:mainStore.count ++,
foo:'hello',
arr:[...mainStore.arr,4]
})
3 批量修改 有性能优化 $patch 函数方式
mainStore.$patch(state=>state.arr.push(4))
4 actions 中 处理逻辑
直接调用 actions 中方法
mainStore.changeState()
也可以 actions中定义 参数
mainStore.changeState2(10)
getters
mainStore.count10
重置数据
mainStore.$reset()
setup 插件 实现 $reset
const app = createApp(App);
const pinia = createPinia();
// use一个 函数 context 上下文 解构
pinia.use(({store})=>{
const initialState = JSON.parse(JSON.stringify(store.$state));
store.$reset = ()=>{
// 对象 需要两次 转换
store.$state = JSON.parse(JSON.stringify(initialState));
}
});
直接替换 整个 state
mainStore.$state = { sex:'男'}
订阅 $patch 触发 无论值 是否改变
mainStore.$subscribe((mutation,state)=>{ mutation.payload })
只有 state 真正改变时才会触发
watch(mainStore.$state,()=>{})
持久化
npm i pinia-plugin-persistedstate
/store/index
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
/store/modules/mainStore.js 文件夹
export const useStore = defineStore('main', {
state: () => {
return {
someState: 'hello pinia',
nested: {
data: 'nested pinia',
},
}
},
// 所有数据持久化
// persist: true,
// 持久化存储插件其他配置
persist: {
// 修改存储中使用的键名称,默认为当前 Store的 id
key: 'storeKey',
// 修改为 sessionStorage,默认为 localStorage
storage: window.sessionStorage,
// [指定 state 中哪些数据需要被持久化],[空] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state。
paths: ['nested.data'],
},
})
第三个参数是一个对象 为持久化
export const useUser = defineStore(
'user',
() => {
// 用户信息
const user = reactive({
token: '',
})
// 返回
return { user }
},
{
persist: {
key: 'user',
storage: window.sessionStorage,
paths: ['user.username'],
},
}
)
非组件 内 使用 即 js ts文件中
要在使用处 函数中 const store = useStore()
而不是 函数外 定义
*/
问题
1 持久化后拿不到 持久数据 改用 ref 定义数据好 可以
ref = state
computed = getter
function = action
2 const store = useTestStore()
store 是 一个 reactive 对象
中 ref(基本数据) .出来还是解构出来 都是 值 没有响应式 --storeToRefs
中 ref({}) .出来还是解构出来 都是 reactive 有响应式
中 reactive .出来还是解构出来 都是 reactive 有响应式
推荐 ref = state
uniapp 持久化 问题 – 项目中 Pinia 用法平时完全一致,主要解决持久化插件兼容性问题
// index.ts
import { createPinia } from 'pinia'
import persist from 'pinia-plugin-persistedstate'
// 创建 pinia 实例
const pinia = createPinia()
// 使用持久化存储插件
pinia.use(persist)
// 默认导出,给 main.ts 使用
export default pinia
// 模块统一导出
export * from './modules/xxx'
// // stores/modules/test.ts
export const useMemberStore = defineStore(
'test',
() => {
//…省略
},
{
// 配置持久化
persist: {
// 调整为兼容多端的API
storage: {
setItem(key, value) {
uni.setStorageSync(key, value)
},
getItem(key) {
return uni.getStorageSync(key)
},
},
},
},
)