Vue 数据缓存方案-Pinia
Pinia 起始于 2019 年 11 月左右的一次实验,其目的是设计一个拥有组合式 API 的 Vue 状态管理库。从那时起,我们就倾向于同时支持 Vue 2 和 Vue 3,并且不强制要求开发者使用组合式 API,我们的初心至今没有改变。除了安装和 SSR 两章之外,其余章节中提到的 API 均支持 Vue 2 和 Vue 3。虽然本文档主要是面向 Vue 3 的用户,但在必要时会标注出 Vue 2 的内容,因此 Vue 2 和 Vue 3 的用户都可以。
1、Pinia 和 Vuex 比较
Vuex 和 Pina 的主要区别在于它们的目的、使用方式、社区支持、数据修改方式、语法和使用、体积以及适用场景。
目的:
- Vuex 是一个专为 Vue.js 应用提供状态管理的库,旨在提供全面的状态管理解决方案,包括模块化、插件和严格模式等功能。
- Pina 是一个轻量级的状态管理库,专注于提供一个简单的 API 来管理应用程序的状态,适合初学者和快速开发项目。
使用方式:
- Vuex 采用全局单例模式,通过一个 store 对象来管理所有的状态,组件通过 store 对象来获取和修改状态。
- Pina 采用了分离模式,每个组件都拥有自己的 store 实例,通过在组件中创建 store 实例来管理状态。
社区支持:
- Vuex 是 Vue.js 官方出品,社区支持较强,拥有丰富的文档和示例。
- Pina 是一个较新的框架,社区支持相对较弱。
数据修改方式:
- Vuex 有 mutations、getters 和 actions,提供了更多的灵活性。
- Pina 没有 mutations,只有 state、getters 和 actions,语法上更简单。
体积:
- Vuex 的体积相对较大,而 Pina 的体积约 1KB,相对较小。
语法和使用:
- Vuex 的语法相对复杂,需要编写复杂的 action、mutation 和 getter 函数。
- Pina 的语法更简单,提供了更好的 TypeScript 支持,更容易理解和使用。
适用场景:
- Vuex 适合复杂的项目和对状态管理有更高要求的开发者。
- Pina 更适合初学者和快速开发项目。
2、Pinia 状态、动作、和获取器
Pinia 的核心概念包括状态(State)、动作(Actions)和获取器(Getters)。这些概念为你提供了一种组织和管理应用状态的方式。
状态(State): 状态是你在 store 中存储的数据。每个 Pinia store 都有自己的状态,这个状态是一个 JavaScript 对象。你可以在定义 store 时初始化状态:
import { defineStore } from 'pinia';
const useStore = defineStore({
id: 'myStore',
state: () => ({
count: 0,
user: null,
}),
});
在这个例子中,count 和 user 就是这个 store 的状态。
动作(Actions): 动作是一种修改 store 状态的方法。在 Pinia 中,你可以在 actions 属性中定义动作:
import { defineStore } from 'pinia';
const useStore = defineStore({
id: 'myStore',
state: () => ({
count: 0,
}),
getters: {
doubleCount() {
return this.count * 2;
},
},
});
在这个例子中,doubleCount 就是一个获取器,它返回 count 的两倍。 通过这些核心概念,Pinia 提供了一种简单而强大的方式来管理和操作你的应用状态。
3、Pinia 基本使用
下面,用一个用户登录存储接口返回 token 的逻辑为例,看一下 Pinia 是如何实现的
1.安装 Pinia
首先,你需要在你的 Vue 项目中安装 Pinia。你可以使用 npm 或 yarn 来安装:
npm install pinia
#或
yarn add pinia
1、main.ts 引入 Pinia
import { creatrePinia } from 'pinia'
const pinia createPinia()
app.use(pinia)
2、创建 Pinia 实例并添加到 Vue 应用
然后,在你的主文件(通常是 main.js 或 main.ts)中,创建一个新的 Pinia 实例,并将其添加到你的 Vue 应用实例中:
import { createPinia } from 'pinia';
import { createApp } from 'vue';
const app = createApp(/* your root component */);
const pinia = createPinia();
app.use(pinia);
app.mount('#app');
3.创建并获取 Store 数据
接下来,你可以开始创建你的 Pinia store。在一个新的文件中,使用 defineStore 函数来定义你的 store:
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
actions: {
increment(count: number) {
this.count = count;
},
},
});
然后在你的 Vue 组件中使用 Store,注:只有经过storeToRefs,store数据才会有响应式
<script lang='ts' setup>
import { storeToRefs } from 'pinia';
import { useCounterStore } from '@/stores/counter';
const counter = useCounterStore();
//解构获取【count】
const { count } = storeToRefs(counter)
const dispathStoreCount = (count: number) => {
//修改store
counter.increment(count)
}
</script>
在实际开发中,遇到了一个问题:
Login 页面登陆后,接口返回 Token,正常逻辑下,我们会在把 Token 存储进 Pinia 里面,然后在 Axios 请求拦截器里面读取 Pinia 的 Token,但发现读取不到,经过排查,发现在读取 Pinia 数据时,将:
const { token } = userStore()
axios.interceptors.request.use(config => {
config.headers.token = token;
})
此行代码,写到了 Axios 页面最顶部,此为初始化,经过修改,将 useStore 操作代码,写入请求拦截器内:
axios.interceptors.request.use(config=> {
const { token } = userStore()
if(token) {
config.headers.token = token;
}
})
这样,就可以解决问题了!
好了,你现在就可以在你的 Vue 项目中使用 Pinia 来管理和操作状态了。更多的信息和高级用法,你可以查阅 Pinia 的官方文档