pinia 状态管理
介绍
Pinia 是 Vue 的专属状态管理库,同时适用于 2he3,它允许你跨组件或页面共享状态。
可以搭配持久化插件一起使用,如:pinia-plugin-persistedstate
特点
- 去除
mutations,比较于 Vuex 更加简单
- 状态管理更简单,更易用
- 支持
options api和composition api
- 全面的
TypeScript支持
- 轻量
- 兼容性 服务端渲染支持
安装
创建实例与引用
1 2 3 4 5
| import { createApp } from "vue"; import pinia from "./stores"; import App from "./App.vue";
createApp(App).use(pinia).mount("#app");
|
使用
定义存储库./store,在文件夹下创建 index.ts 作为总导出文件,再创建 modules 文件夹,创建对应的模块文件,如user.ts
定义模块
1 2 3 4 5 6 7 8 9 10 11 12
| # index.ts import { createPinia } from 'pinia' import persist from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(persist)
export default pinia
export * from './modules/user'
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # 定义示例一 import { defineStore } from "pinia"; # counter是唯一的模块标识符,不能重复 export const useCounterStore = defineStore("counter", { state: () => ({ count: 0, name: "Eduardo" }), getters: { doubleCount: (state) => state.count * 2, }, actions: { increment() { this.count++; }, }, });
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # 定义示例二 export const useCounterStore = defineStore('counter', () => { # state const count = ref(0) const name = ref('Eduardo') # action const doubleCount = computed(() => count.value * 2) # getter function increment() { count.value++ }
return { count, name, doubleCount, increment } })
|
在组件中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <script setup> import { useCounterStore } from '@/stores/counter' import { computed } from 'vue'
const store = useCounterStore() // 解构之后会失去响应式 const { name, doubleCount } = store // name 将会一直是 "Eduardo" // doubleCount 将会一直是 0 setTimeout(() => { store.increment() }, 1000) // ✅ 而这一部分代码就会维持响应式 // 💡 在这里你也可以直接使用 `store.doubleCount` const doubleValue = computed(() => store.doubleCount) </script>
|
可以使用 storeToRefs 保持响应式
1 2 3 4 5
| import { useCounterStore } from "@/stores/counter"; import { storeToRefs } from "pinia"; const store = useCounterStore(); const { name, doubleCount } = storeToRefs(store); # 在Option API中 需要使用辅助函数 mapState
|
数据重置
1 2 3 4 5 6 7 8
| # $reset()将store重置为初始状态 import { useCounterStore } from "@/stores/counter";
const counterStore = useCounterStore();
function resetData() { counterStore.$reset(); }
|
插件
由于有了底层 API 的支持,Pinia store 完全支持各类扩展。
插件是通过 pinia.use() 添加到 pinia 实例的。最简单的例子是通过返回一个对象将一个静态属性添加到所有 store。
1
| pinia.use(() => ({ hello: "world" }));
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import { createPinia } from "pinia";
function SecretPiniaPlugin() { return { secret: "the cake is a lie" }; }
const pinia = createPinia();
pinia.use(SecretPiniaPlugin);
const store = useStore(); store.secret;
|
<<< more >>>
其他:
zustand(nextjs)
vuex(vue)
redux(react)