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}
)