1.state
state 就是我们要定义的数据, 如果定义 store 时传入的第二个参数是对象, 那么 state 需要是一个函数, 这个函数的返回值才是状态的初始值.这样设计的原因是为了让 Pinia 在客户端和服务端都可以工作
官方推荐使用箭头函数(()=>{ })获得更好的类型推断
import { defineStore } from 'pinia';
const userStore = defineStore('user', {
state: () => {
return {
user: {
name: 'tom',
age: 18
},
color: 'red',
userList: [],
}
}
})
2.TypeScript
可以定义 interface 来标记类型
import { defineStore } from 'pinia';
interface UserInfo {
name: string;
age: number;
}
export const userStore = defineStore('user', {
state: () => {
return {
color: 'red' as string,
userList: [] as UserInfo[],
user: {
name: 'tom',
age: 18
} as UserInfo | null
}
}
})
3.访问 state
默认可以直接通过 store 实例访问和修改 state.
const user = userStore();
function changeColor() {
user.color = 'black'
}
function changeAge() {
user.user.age++;
}
4.重置 state
调用 store 的 $reset()
function resetStore() {
user.$reset();
}
5.修改 state
除了直接通过 store 修改 state, 还可以调用 store 的 $patch 方法. 这个方法允许一次进行多处修改
function patchChange() {
user.$patch({
color: 'skyblue',
user: {
age: user.user.age + 10
}
})
}
但是这种语法有时会很麻烦, 比如我们想要对数组进行增删时, 这种语法会要求创建一个新的数组. 所以 $patch 方法可以接收一个函数为参数.
function patchChangeFunction() {
user.$patch((state) => {
state.userList.push({ name: 'mike', age: 19 });
state.user.age++;
state.color = 'pink';
});
}
也直接通过 store 的 $state 属性修改 state, 因为其内部会调用 $patch
function stupidChange() {
user.$state = {
color: 'hahha'
}
// 实际上内部调用了
// user.$patch({ color: 'hahha' })
}
6.订阅状态
我们可以通过 store 的 $subscribe 方法侦听 state 的改变. 使用 $subscribe 而不是 watch() 的好处是 $subscribe 总是在 state 修改之后执行一次.
user.$subscribe((mutation, state) => {
console.log('mutation', mutation);
})
const stopSubscribeFunc = user.$subscribe((mutation, state) => {
console.log('mutation', mutation);
console.log('state', state);
})
function stopSubscribe() {
stopSubscribeFunc()
}
如果在组件内调用 store.$subscribe(), 那么组件卸载时会自动清理定于, 除非将 detached 设置为 true
user.$subscribe((mutation, state) => {
// do something...
}, {
detached: true
})
如果要实现保存数据到 localStorage, 可以使用 watch
//main.js里
const pinia = createPinia();
app.use(pinia);
watch(
pinia.state,
(state) => {
console.log(state)
localStorage.setItem('piniaState', JSON.stringify(state));
},
{
deep: true,
immediate: true
}
)