Pinia 是一个基于 Vue 3 的状态管理库,它的目标是提供更好的类型支持和更好的利用 TypeScript 特性的方式来进行状态管理。相比于 Vuex 等其他状态管理库,它使用起来更加简单、轻量级、可维护性更高。
Pinia 的主要特点包括:
总之,Pinia 是一个非常优秀的状态管理库,在 Vue 3 项目中使用 Pinia 可以提高代码的可维护性和可测试性,同时还可以获得更好的开发体验和更好的类型推导支持。
Pinia 官方文档
npm install pinia
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
import { createPinia } from "pinia";
const app = createApp(App);
//支持Pinia
app.use(createPinia());
app.mount("#app");
Store承载着全局状态。它有点像一个始终存在并且每个人都可以读取和写入的组件。
它有三个概念,state、getters 和 actions 并且可以安全地假设这些概念等同于组件中的“数据”、“计算”和“方法”。
在src
目录下新建stores
文件夹,并在stores
目录下新建index.js
文件。
state 是 store 的核心部分。
类似于Vue3中的data。
定义Store
import { defineStore } from "pinia";
export const useUserStore = defineStore("user", {
state: () => {
return { name: "小明", age: 30, address: "北京", arr: [1, 2, 3] };
}
});
使用State
姓名:{{ userStore.name }} 年龄:{{ userStore.age }} 地址:{{ userStore.address }} 数组:{{ userStore.arr }}
Getter类似于Vue3中的计算属性。
定义Store
import { defineStore } from "pinia";
export const useUserStore = defineStore("user", {
state: () => {
return { name: "小明", age: 30, address: "北京", arr: [1, 2, 3] };
},
getters: {
gettersAge: (state) => {
console.log("state", state);
return state.age + 10;
},
gettersAge2() {
//this指向store
return this.age + 10;
},
gettersNameAge: (state) => {
return state.name + "-" + state.age;
},
//调用其他state,但是getter不再缓存
gettersOther() {
const counterStore = useCounterStore();
return this.age + counterStore.counter;
},
}
});
使用Getters
{{ userStore.gettersAge }}
{{ userStore.gettersAge2 }}
{{ userStore.gettersNameAge }}
{{ userStore.gettersOther }}
Action类似于Vue3中的methods,支持异步操作。
定义Store
import { defineStore } from "pinia";
export const useUserStore = defineStore("user", {
state: () => {
return { name: "小明", age: 30, address: "北京", arr: [1, 2, 3] };
},
actions: {
//不能使用箭头函数
addAge() {
//this指向store
this.age++;
},
},
});
使用Actions
姓名:{{ userStore.name }} 年龄:{{ userStore.age }} 地址:{{ userStore.address }} 数组:{{ userStore.arr }}
与 Vue 组合式 API 的 setup 函数 相似,我们可以传入一个函数,该函数定义了一些响应式属性和方法,并且返回一个带有我们想暴露出去的属性和方法的对象。
ref()
就是 state
属性computed()
就是 getters
function()
就是 actions
定义store:
export const useCounterStore = defineStore("counter", () => {
// state
const counter = ref(30);
// getters
const gettersCounter = computed(() => {
return counter.value + 5;
});
// actions
function addCounter() {
counter.value++;
}
function subCounter() {
counter.value--;
}
return { counter, gettersCounter, addCounter, subCounter };
});
使用:
{{ counterStore.counter }}
{{ counterStore.gettersCounter }}
解构操作会丢失响应式,可以使用storeToRefs()
函数保持响应式。
{{ counter }}
{{ gettersCounter }}
npm i pinia-plugin-persistedstate
import { createApp } from "vue";
import "./style.css";
import App from "./App.vue";
import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
const app = createApp(App);
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate); //添加插件
app.use(pinia);
app.mount("#app");
export const useCounterStore = defineStore(
"counter",
() => {
// state
const counter = ref(30);
const num = ref(10);
// getters
const gettersCounter = computed(() => {
return counter.value + 5;
});
// actions
function addCounter() {
counter.value++;
}
function subCounter() {
counter.value--;
}
function addNum() {
num.value++;
}
return { counter, num, gettersCounter, addCounter, subCounter, addNum };
},
{
persist: true, //开启当前模块的持久化
}
);
export const useCounterStore = defineStore(
"counter",
() => {
// state
const counter = ref(30);
const num = ref(10);
// getters
const gettersCounter = computed(() => {
return counter.value + 5;
});
// actions
function addCounter() {
counter.value++;
}
function subCounter() {
counter.value--;
}
function addNum() {
num.value++;
}
return { counter, num, gettersCounter, addCounter, subCounter, addNum };
},
{
persist: {
key: "hello", // 唯一标识
paths: ["num"], //只保持num
},
}
);