npm install pinia --save
// or
npm i pinia -S
import { defineStore } from 'pinia';
// options API模式
export const usePersonStore = defineStore('person', {
state: () => {
return {
name: '人类'
};
},
actions: {
updateName(newName) {
this.name = newName;
}
},
getters: {
// getters基本与Vue的计算属性一致
getFullName() {
return 'Full' + this.name;
}
}
});
// 对象形式
export const useTeacherStore = defineStore({
id: 'teacher',
state: () => {
return {
name: '老师'
};
},
actions: {
updateName(newName) {
this.name = newName;
}
},
getters: {
getFullName() {
return 'Full' + this.name;
}
}
});
// setup模式
import { computed, ref } from 'vue';
export const useStudentStore = defineStore('student', () => {
const name = ref('学生');
function updateName(newName) {
name.value = newName;
}
const getFullName = computed(() => 'Full' + name.value);
return { name, updateName, getFullName };
});
2.1 pinia-plugin-persist 最新版本为 1.0.0 ;配套的 pinia 版本为>=2.0.0 && < 3.0.0
npm i pinia-plugin-persist -S
// 在 src/store/index.js 中引入 pinia-plugin-persist 插件:
import { createPinia } from 'pinia';
import piniaPluginPersist from 'pinia-plugin-persist';
const pinia = createPinia();
pinia.use(piniaPluginPersist);
export default pinia;
// 在对应的 src/store/info.js 中开启缓存:
import { defineStore } from 'pinia';
import { useOtherStore } from './other';
export const useInfoStore = defineStore('info', {
state: () => {
return {
name: '橙某人',
age: 18
};
},
getters: {
getHobby() {
return this.name;
// return useOtherStore().hobby;
}
},
persist: {
enabled: true, // 开启缓存
strategies: [
{
key: 'infoStore', // 修改缓存的key
storage: localStorage, // 指定localStorage作为缓存
paths: ['name'] // 只缓存name
}
]
}
});
2.2. 使用
<script setup>
import { storeToRefs } from 'pinia';
import useFormInfoStore from '@/store/formInfo';
import { readonly } from 'vue';
const formInfoStore = useFormInfoStore();
// 解构出state
const { age, name } = storeToRefs(formInfoStore);
// 1. **因为直接修改state中的属性;不建议这么做,很难知道在哪改了数据**
formInfoStore.age++; // 19
// 解决方案:
const readonlyStore = readonly(formInfoStore);
readonlyStore.age++; // 这样就会报错,提示不能修改只读的对象
// 2 .$reset 重置状态,将状态重置成为初始值
formInfoStore.$reset();
console.log(formInfoStore.age); // 18
// 3.$patch 支持对state对象的部分批量修改
formInfoStore.$patch({
name: 'hello Vue',
age: 198
});
// 4.$state 通过将其 $state 属性设置为新对象来替换 Store 的整个状态
formInfoStore.$state = {
name: 'hello Vue3',
age: 100,
gender: '男'
};
// 4.$subscribe 订阅store中的状态变化
formInfoStore.$subscribe(
(mutation, state) => {
// 监听回调处理
},
{
detached: true // 💡如果在组件的setup中进行订阅,当组件被卸载时,订阅会被删除,通过detached:true可以让订阅保留
}
);
</script>
3.1 src/store/index.js
import { createPinia } from 'pinia';
import piniaPluginPersist from 'pinia-plugin-persistedstate';
const pinia = createPinia();
pinia.use(piniaPluginPersist);
export default pinia;
3.2 src/store/info.js
import { defineStore } from 'pinia'
interface UserState {
readonly name: string
id: number | null
}
export const useStore = defineStore('user', {
state: () => ({
name: 'zhangsan',
id: null,
}),
getters: {
getName(): string {
return this.name
},
},
actions: {
setName(newName: string) {
// this.name = newName
;(this as { name: string }).name = newName
},
},
persist: {
storage: localStorage,
pick: ['name'],
},
})
3.3 使用
import { useStore } from '@/store/modules/user.ts'
import { storeToRefs } from 'pinia'
const _useStore = useStore()
const readonlyStore = readonly(_useStore)
readonlyStore.name = '王五' // 不能修改只读的对象,警告报错且不会更新数据
readonlyStore.setName('李11')
const unsubscribe = formInfoStore.$onAction(
({
name, // action 的名字
store, // store 实例
args, // 调用这个 action 的参数
after, // 在这个 action 执行完毕之后,执行这个函数
onError // 在这个 action 抛出异常的时候,执行这个函数
}) => {
// 记录开始的时间变量
const startTime = Date.now();
// 这将在 `store` 上的操作执行之前触发
console.log(`Start "${name}" with params [${args.join(', ')}].`);
// 如果 action 成功并且完全运行后,after 将触发。
// 它将等待任何返回的 promise
after(result => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
);
});
// 如果 action 抛出或返回 Promise.reject ,onError 将触发
onError(error => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
);
});
}
);
// 手动移除订阅
unsubscribe();