前言
什么是pinia
Pinia 是 Vue 新一代的状态管理器。同时适用于 Vue 2 和 Vue 3。在vue3中有人可能会使用export const state = reactive({})来共享全局状态. 但是这样在SPA页面中还行,在SSR应用中则会出现 安全漏洞
pinia的特点
- 支持
options api和composition api - 去除
mutations比vuex更加精简 - 在页面或者组件直接引用后使用, 数据来源更加清晰调试更加方便
- 全面的
TypeScript支持 - 服务器端渲染支持
- 轻量 压缩后的体积只有1kb左右
下载
npm install pinia --save
//或
yarn add pinia
使用
// main.js
import { createPinia } from 'pinia'
app.use(createPinia())
-
定义state 和 getters
//Public.js import { defineStore } from 'pinia' export const PublicStore = defineStore('Public', { // Public项目唯一id state: () => { return { userMsg: {}, } }, getters: { getUserMsg: (state) => { return state.userMsg }, }, // other options... }) -
访问state 和 getters 两者的使用非常相似
- 在
Composition API中import { PublicStore } from '@/store/Public' const store = PublicStore() console.log(store.getUserMsg.userName, store.userMsg.token) // 可以访问state 和 getters const { getUserMsg, userMsg } = { ...PublicStore() } // 可以直接解构但是会失去响应式 console.log(getUserMsg.userName, userMsg.token) - state直接解构会使其失去响应式,这时候可以用 pinia 的
storeToRefsimport { PublicStore } from '@/store/Public' import { storeToRefs } from 'pinia' const { getUserMsg, userMsg } = storeToRefs(PublicStore()) // 保持响应式使用storeToRefs console.log(getUserMsg.value.userName, userMsg.value.token) - 在
Option API中 需要使用辅助函数mapStateimport { PublicStore } from '@/store/Public' import { mapState } from 'pinia' export default { name: 'Home', computed: {// 获取state和getters 使用的方法类似 ...mapState(PublicStore, ['getUserMsg', 'userMsg']), // 直接获取state和getters ...mapState(PublicStore, { aliasUserMsg: 'userMsg', // 获取state 并重命名 aliasGetUserMsg: 'getUserMsg',// 获取getters 并重命名 userName: store => store.userMsg.userName + store.getUserMsg.token, // 使用函数访问 state 或者getters getTooken(store) { // 使用非箭头函数访问 可以在函数中使用 this return [store.getUserMsg, store.userMsg, this.getUserMsg] } }), } };
- 在
-
定义actions
// public.js import { defineStore } from 'pinia' import { Auth } from './auth' //使用其他的store export const PublicStore = defineStore('Public', { // other options... actions: { setUserMsg(userMsg) { this.userMsg = userMsg }, async setUserMsgToken(userMsg) { // 同步的action const authStore = Auth() let res = await authStore.setPower() // 使用其他store if (res) { userMsg.authList = authStore.power this.userMsg = userMsg return true } else { return false } } } })// auth.js import { defineStore } from 'pinia' import api from '@/api' export const Auth = defineStore('Auth', { state: () => { return { power: [], } }, // other options... actions: { async setPower() { let res = await api.BaseApi.getPower() // 在store中使用xhr if (res.code === 200) { this.power = res.data return true } } } }) -
使用actions
-
在Composition API中
import { PublicStore } from '@/store/Public' const store = PublicStore() const update = async () => { // store.userMsg = {userName: '涵涵', token: '234523423423423',authList: []} // 不推荐直接接修改 建议通过 actions 去修改 state let power = await store.setUserMsgToken({ userName: '涵涵',token: '234523423423423',authList: [] }) if (power) { // 修改成功 } else { // 修改失败 } } -
在Option API中 使用
mapActions辅助函数import { PublicStore } from '@/store/Public' import { mapActions } from 'pinia' export default { name: 'Home', methods: { ...mapActions(PublicStore, ['setUserMsg']), ...mapActions(PublicStore, { setUserMsgToken: 'setUserMsgToken' }), async update() { // this.userMsg.userName = '涵行' // 不推荐直接接修改 建议通过 actions 去修改 state let power = await this.setUserMsgToken({userName: '憨憨',token: '54735634545',authList: [] }) if (power) { // 修改成功 } else { // 修改失败 } }, } };
-
-
重置数据
reset//Composition API import { PublicStore } from '@/store/Public' const store = PublicStore() store.$reset() // Option API import { PublicStore } from '@/store/Public' export default { methods: { reset() { const store = PublicStore() // 只在某个函数中使用 store.$reset() // 重置state 为初始值 } } };