vue3 Vuex和Pinia 状态管理实践
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