-
可替代vuex的插件
例子
import { defineStore } from 'pinia';
import { store } from '@/store';
/**
* 各种需共享的临时数据
*/
const recovery = {
device: { tab: 'device', orderId: '', status: '' },
log: { tab: 'log', orderId: '', assetId: '' },
};
const orderPhy = {
delivery: { tab: 'delivery', orderId: '' },
};
type User = {
name: string;
age: number;
};
const result: User = {
name: 'menffy2',
age: 999,
};
const Login = (): Promise<User> => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({
name: 'menffy3',
age: 999,
});
}, 2000);
});
};
export const shareValueStore = defineStore('shareValue', {
state: () => ({
recovery,
orderPhy,
current: 1,
name: 'menffy',
user: <User>{},
}),
// computed修饰一些值
getters: {
recoveryDeviceData: (state) => {
return state.recovery.device;
},
recoveryDeviceLogData: (state) => {
return state.recovery.log;
},
orderPhyDeliveryData: (state) => {
return state.orderPhy.delivery;
},
newVal(): string {
return `$-${this.name}-${this.getUserAge}`;
},
getUserAge(): number {
return this.user.age;
},
},
// methods 可以做同步或异步操作,提交state
actions: {
// 同步
setRecovery(choice, data) {
if (choice === 'device') {
this.recovery.device = data;
} else {
this.recovery.log = data;
}
},
setOrderPhy(data) {
this.orderPhy.delivery = data;
},
setCurrent(num: number) {
this.current = num;
},
setUser() {
this.user = result;
},
// 异步
async setAsyncUser() {
this.user = await Login();
this.setName('menffy4');
},
setName(name: string) {
this.name = name;
},
},
});
// 可以不要的
export function getShareValueStore() {
return shareValueStore(store);
}
使用
<template>
<div>
<div>pinina</div>
<div>直接读取store</div>
<div>{{ share.current }}</div>
<div>{{ share.name }}</div>
<div>{{ share.user }}</div>
<div>getter: {{ share.newVal }}</div>
<div>解构读取store</div>
<div>{{ current }}</div>
<div>{{ name }}</div>
<t-button @click="onChange">change</t-button>
<t-button @click="reset">reset</t-button>
</div>
</template>
<script setup lang="ts">
import { useShareValueStore } from '@/store';
import { storeToRefs } from 'pinia';
const share = shareValueStore();
// store解构
const { current, name } = storeToRefs(share);
const onChange = () => {
console.log("五种方式修改state,具体逻辑可参见下方");
};
</script>
五种方式修改state
1、直接修改
const onChange = () => {
share.current++;
share.name = '123';
};
2、$patch批量修改
const onChange = () => {
console.log('onChange');
share.$patch({
current: 123,
name: '123',
});
};
3、$patch批量修改
- 工厂函数形式,可以在内部实现逻辑
const onChange = () => {
share.$patch((state) => {
state.current = 3;
state.name = 'no3';
});
};
4、$state
- 弊端:必须修改整个对象,即state里定义的所有对象都必须修改,比较少用
const onChange = () => {
share.$state = {
current: 4,
name: 'no4',
};
};
5、defineStore里定义action动作
const onChange = () => {
// 同步
share.setCurrent(5);
// 异步
// share.setAsyncUser();
};
pinia解构store
- 在pinia里是不可以直接解构的,会使其失去响应性
- 使用官方提供api解构即可,原理与toRefs类似
import { useShareValueStore } from '@/store';
import { storeToRefs } from 'pinia';
const share = useShareValueStore();
const { current, name } = storeToRefs(share);
const onChange = () => {
// 直接对store的变量做修改,同时影响解构的值和store里的值
// share.current++;
// 对解构出来的变量做修改,同时影响解构的值和store里的值
current.value++;
};
实例的其他API
$reset 重置
// 修改值
const onChange = () => {
share.setUser();
};
// 重置为初始值
const reset = () => {
share.$reset();
};
$subscribe 订阅
// 修改值
const onChange = () => {
share.setUser();
};
// 订阅
// 任何一个值有变化都会被捕捉到,类似watch
share.$subscribe((args, state) => {
console.log('args====>', args);
console.log('state====>', state);
},
// 参数和watch类似
{
detached: true, // true表示,当前组件就算被销毁了,也要继续监听
deep: true, // 递归监听
flush: 'post',
},
);
订阅输出:
$onAction 监听
// 修改值
const onChange = () => {
// 参数也会被捕获到
share.setName('otherName');
};
// 一调用action里的方法就会被监听到
share.$onAction((args) => {
args.after(() => {
console.log('after,清除副作用,"args-action"之后才会执行');
});
console.log('args-action====>', args);
}, true); // 这里的true表示,当前组件就算被销毁了,也要继续监听