pinia使用指南

8,913 阅读2分钟

前言

什么是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 的 storeToRefs
      import { PublicStore } from '@/store/Public'
      import { storeToRefs } from 'pinia'
      const { getUserMsg, userMsg } = storeToRefs(PublicStore()) // 保持响应式使用storeToRefs
      console.log(getUserMsg.value.userName, userMsg.value.token)
      
    • Option API中 需要使用辅助函数 mapState
      import { 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 为初始值
            }
        }
    };