官方给出的理由是:API 更简单、更简洁,对 TypeScript 更友好
- 没 mutations
- 没 名称空间,但有模块概念
- TypeScript 类型支持无需额外 warps 支持
- 存储默认为动态的
- 不再嵌套模块结构
// 基本用法
import { createPinia, defineStore } from 'pinia';
// 初始化
app.use(createPinia());
// 定义一相模块
export const useSomeModuleStore = defineStore('someModule', {
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2,
},
actions: {
increment() {
this.count++;
},
},
});
// or
defineStore('someModule', () => {
const count = ref(0);
const double = computed(() => store.doubleCount);
function increment() {
count.value++;
}
return { count, double, increment };
});
// use
const store = useSomeModuleStore();
console.log('store.count', store.count++);
// 重置
store.$reset();
// 同时修改多个属性
store.$patch({ count: store.count + 1 });
// 复杂属性
store.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 });
});
// ❌ 解构会破坏它的响应式
const { count } = store;
// ✅ 但这样可以
const { count } = storeToRefs(store);
// 订阅
store.$subscribe((mutation, state) => {
// 每当状态发生变化时,将整个 state 持久化到本地存储。
localStorage.setItem('xxx', JSON.stringify(state));
});
访问其它模块的 state、getter 或 action 同在组件中访问它们一样
VUEX | Pinia |
---|---|
根部 new Vue({store }) 注入 | app.use(createPinia()) |
namespace | defineStore('someModule', {...}) |
state | state or someState = ref(x) |
getters | getters |
mutations | store.$patch(...) |
actions | actions |
subscribe(监听 mutation 调用) | store.$subscribe 只能监听整体,非某个属性 |
this.$store.someModule.state.x |
const { x } = storeToRefs(useSomeModuleStore()) |
this.$store.someModule.getters.x |
同上 |
this.$store.commit('xx') |
const { xx } = useSomeModuleStore(); xx() |
this.$store.dispatch('xx') |
同上 |
Plugins
function SecretPiniaPlugin() {
// 添加全局状态 secret
return { secret: 'the cake is a lie' };
}
const pinia = createPinia();
// 将该插件交给 Pinia
pinia.use(SecretPiniaPlugin);
app.use(pinia);
// 在另一个文件中
someStore.secret; // 'the cake is a lie'
// d.ts
pinia.use(plugin: PiniaPlugin): Pinia;
PiniaPlugin = (context: PiniaPluginContext) => object | void
PiniaPluginContext = {
pinia: Pinia;
app: App;
// 该插件想扩展的 store
store: Store<Id, S, G, A>;
// 定义传给 `defineStore()` 的 store 的可选对象。
options: DefineStoreOptionsInPlugin<Id, S, G, A>;
}
添加外部属性、第三方库的类实例或非响应式的简单值时,
import { markRaw } from 'vue';
// 根据你的路由器的位置来调整
import { router } from './router';
pinia.use(({ store }) => {
store.router = markRaw(router);
});