Vue 3 引入全局状态管理 pinia
什么是全局状态管理?
所有页面全局共享的变量,而不是局限在某一个页面中。适合作为全局状态的数据: 已登录用户信息 (每个页面几乎都要用) Pinia 是一个主流的状态管理库,相比于 Vuex 来说使用更简单,可参考 入门文档 开始 | Pinia 进行引入 ;
1、引入 Pinia
此处由于 create-vue 脚手架已经帮我们整合了 Pinia,无需手动引入,直接使用即可
或者没有整合的话,使用命令安装 :
yarn add pinia
# 或者使用 npm
npm install pinia
此处是使用 vue - create 脚手架自动生成的,这里举了一个管理一个计数器的状态的例子。
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
//一个状态就存储一类要共享的数狱(存一类常量)
// 使用 defineStore 定义了一个名为 'counter' 的 store。创建了一个简单的计数器 store,允许获取当前计数、获取计数的两倍值,并提供增加计数的功能
// 这个 store 包含了三个主要部分:状态(state)、计算属性(getters)和动作(actions)。
export const useCounterStore
= defineStore('counter', () => {
//定义状志的初始值 count = ref(0):定义了一个名为 count 的响应式变量,初始值为 0。这个变量用于存储计数器的当前值。
//定义受量的计算逻辑 getter
const count = ref(0)
// 定义了一个计算属性 doubleCount,它始终返回 count 的两倍值。当 count 发生变化时,doubleCount 会自动更新。
const doubleCount = computed(() => count.value * 2)
// 定义怎么更改状态的方法 定义了一个方法 increment,用于将 count 的值加 1。
function increment() {
count.value++
}
// 返回 ,导出 Store
return { count, doubleCount, increment }
})
2、定义状态
在 src/stores 目录下定义 user 模块,定义了用户的存储、远程获取、修改逻辑 :
import { defineStore } from "pinia";
import { ref } from "vue";
export const useLoginUserStore = defineStore("loginUser", () => {
const loginUser = ref<any>({
userName: "未登录",
});
async function fetchLoginUser() {
// todo 由于后端还没提供接口,暂时注释
// const res = await getCurrentUser();
// if (res.data.code === 0 && res.data.data) {
// loginUser.value = res.data.data;
// }
}
function setLoginUser(newLoginUser: any) {
loginUser.value = newLoginUser;
}
return { loginUser, setLoginUser, fetchLoginUser };
});
3、使用状态
可以直接使用 store 中导出的状态变量和函数。
在首次进入到页面时,一般会尝试获取登录用户信息。修改 App.vue,编写远程获取数据代码:
const loginUserStore = useLoginUserStore()
loginUserStore.fetchLoginUser()
在任何页面中都可以使用数据,比如 GlobalHeader 全局顶部栏组件中直接展示:
{{ JSON.stringify(loginUserStore.loginUser) }}
修改全局顶部栏组件,在右侧展示登录状态
<div class="user-login-status">
<div v-if="loginUserStore.loginUser.id">
{{ loginUserStore.loginUser.userName ?? '无名' }}
</div>
<div v-else>
<a-button type="primary" href="/user/login">登录</a-button>
</div>
</div>
4、测试全局状态管理
在 userstore 中编写测试代码,测试用户状态的更新:
async function fetchLoginUser() {
// 测试用户登录,3 秒后登录
setTimeout(() => {
loginUser.value = { userName: '测试用户', id: 1 }
}, 3000)
}