likes
comments
collection
share

vue3 Vuex和Pinia 状态管理实践

作者站长头像
站长
· 阅读数 16

Pinia和Vuex一样都是是vue的全局状态管理器。其实Pinia就是Vuex5,只不过为了尊重原作者的贡献就沿用了这个看起来很甜的名字Pinia。

本文将通过Vue3的形式对两者的不同实现方式进行对比,让你在以后工作中无论使用到Pinia还是Vuex的时候都能够游刃有余。

既然我们要对比两者的实现方式,那么我们肯定要先在我们的Vue3项目中引入这两个状态管理器,但现实工作中我们只能二选一,不能两个同时使用。

注意:vuex的状态储存在仓库的state属性中,state是只读的,无法直接修改必须调用mutation才能修改

1.下面我们先来讲讲Vuex

第一步:npm i vuex --save/-S

第二步: 创建store.js 

第三步:挂载使用        Vue.use(vuex)

第四步:const store = new Vuex.Store({...配置项})

第五步:导出 export default store

第六步:导入main.js 在根实例配置 store 选项指向 store 实例对象

具体过程如下:

npm i vuex -S

项目中调用挂载,在src目录下新建store目录即可;

新建store/store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
// 创建基本状态
const state = {
 // 登录状态为没登录
 logined: false,
 // 用户信息数据,目前只需要avatar和name,还是把username也加上吧
 LoginedUser: {
  name: '',
  avatar: '',
  username: ''
 }
}
// 创建改变状态的方法
const mutations = {
 // 改变状态的方法也需要2个,一个是登录或注册了,一个是登出了
 // 这里不能写箭头函数???
 // 登录
 LOGIN (state) {
  // 先让登录状态变为登录了
  state.logined = true
  // 然后去sessionStorage取用户数据
  let user = JSON.parse(sessionStorage.getItem('user'))
  // 再把用户数据发下去
  state.LoginedUser.name = user.name
  state.LoginedUser.avatar = user.avatar
  state.LoginedUser.username = user.username
 },
 // 登出
 LOGOUT (state) {
  // 这个同理
  state.logined = false
  state.LoginedUser.name = ''
  state.LoginedUser.avatar = ''
  state.LoginedUser.username = ''
 }
}
// 创建驱动actions可以使得mutations得以启动
const actions = {
 // 这里先来一个驱动LOGIN的东西就叫login吧
 // 这个context是官方写的,应该叫什么无所谓
 login (context) {
  context.commit('LOGIN')
 },
 // 同样来个logout
 logout (context) {
  context.commit('LOGOUT')
 }
}

export default new Vuex.Store({
 state,
 mutations,
 actions
})

main.js引入:

import { createApp } from 'vue'  
import App from './App.vue'  
import store from '@/store'  
createApp(App).use(store).mount('#app')

App.vue使用:

<template>  
  <div></div>  
</template>  
<script setup>  
import { useStore } from 'vuex'  
let vuexStore = useStore()  
console.log(vuexStore.state.LoginedUser); 
修改状态:
// 在组件中直接出发mutaion
useStore.commit('LOGIN', true) 
</script>

2.pinia 是 Vue 的存储库,它允许您跨组件/页面共享状态。就是和vuex一样的实现数据共享。 依据Pinia官方文档,Pinia是2019年由vue.js官方成员重新设计的新一代状态管理器,更替Vuex4成为Vuex5。 Pinia 目前也已经是 vue 官方正式的状态库。适用于 vue2 和 vue3。可以简单的理解成 Pinia 就是 Vuex5。也就是说, Vue3 项目,建议使用Pinia。

具体过程如下:

npm i pinia -S

项目中调用挂载,在src目录下新建store目录即可;

新建store/pinia.js


    // defineStore 调用后返回一个函数,调用该函数获得 Store 实体
    export const GlobalStore = defineStore({
      // id: 必须的,在所有 Store 中唯一
      id: "myGlobalState",
      // state: 返回对象的函数
      state: () => ({
        a: 1,
      }),
      getters: {},
      actions: {
        setXXX(number) {
          this.a = number;
        },
      },
    });

    // 在vue3中使用
    <template>
        <div>
            {{number}}
            <button @click="clickHandle">按钮</button>
        </div>
    </template>
    <script>
    import {GlobalStore} from "@/store/store.js"
    export default {
        setup(){
            let store = GlobalStore();
            // ⭐⭐⭐ 如果直接取state的值必须使用computed才能实现数据的响应式 如果直接取 store.state.a 则不会监听到数据的变化,或者使用getter,就可以不使用computed (这边和vuex是一样的)
            let number = computed(()=>store.a)
            const clickHandle = () => {
                store.setXXX("100")
            }
            return{number,clickHandle}
        }
    }
    <script>

相比于Vuex,Pinia是可以直接修改状态的,并且调试工具能够记录到每一次state的变化:

<template>  
  <div>{{ piniaStoreA.piniaMsg }}</div>  
</template>  
<script setup>  
import { store } from '@/store/pinia'  
let piniaStore = store()  
console.log(piniaStore.state); //hello pinia  
  
piniaStore.state.a = 2;  
console.log(piniaStore.state);      
</script>
转载自:https://juejin.cn/post/7241452728747294781
评论
请登录