Pineapple
Define a Store
import {
defineStore } from 'pinia'
export const useStore = defineStore('main', {
})
This name , also known as id , is necessary and is used by Pinia to connect the store to devtools.
Naming the returned function use... is a convention across composables to make it what you're used to.
use store
import {
useStore } from '@/stores/counter'
const storeObj = useStore()
console.log(storeObj.count)
Once the store is instantiated, you can directly access any properties defined on the store state
, getters
andactions
store
is anreactive
object wrapped with , which means there is no need to write after the getter.value
,Like
setup
inprops
, we cannot destructure it
In order to extract properties from the Store while keeping it responsive, you need to usestoreToRefs()
import {
useStore } from '@/stores/counter'
const {
count } = useStore()
console.log(count)//失去响应
#解决
import {
storeToRefs } from 'pinia'
const {
count } = storeToRefs(useStore())
console.log(count.value)
state
In Pinia, states are defined as functions that return an initial state.
const useStore = defineStore('main', {
state: () => {
return {
count: 0}
})
access "state"
const storeObj = useStore()
store.count++
reset status
const storeObj = useStore()
storeObj.$reset()
change status
Can be modified by evil: store.count++
You can call the $patch method
storeObj.$patch({
otherProp: 'main'//其他属性
count: storeObj.count + 1
})
or
storeObj.$patch((state) => {
state.item.push({
name: 'RenNing', age: 18})
state.count = ++state.count
})
$patch
The method also accepts a function to batch modify some objects in the collection
replacestate
store.$state = {
counter: 666, name: 'Paimon' } //{ counter: 666, name: 'Paimon' }
store.$state = {
}
Only for the original defined attributes, although undefined data will be added, but it will not work
subscription status
$subscribe()
View the state and its changes through the store method
The advantage of watch()
using over regular is that subscriptions will only be triggered once after patches$subscribe()
storeObj.$subscribe((mutation, state) => {
// import { MutationType } from 'pinia'
mutation.type // 'direct' | 'patch object' | 'patch function'
// 与 cartStore.$id 相同
mutation.storeId // 'cart'
// 仅适用于 mutation.type === 'patch object'
mutation.payload // 补丁对象传递给 to cartStore.$patch()
// 每当它发生变化时,将整个状态持久化到本地存储
localStorage.setItem('cart', JSON.stringify(state))
})
By default, state subscriptions are bound to the component that added them
They will be automatically removed when the component is unmounted
If you want to keep components after they are unmounted, pass { detached: true }
as the second argument to detach the current component's state subscription
storeObj.$subscribe(callback, {
detached: true})
You can
pinia
view the entire status on the instance:watch( pinia.state, (state) => { // 每当它发生变化时,将整个状态持久化到本地存储 localStorage.setItem('piniaState', JSON.stringify(state)) }, { deep: true } )
getter
defineStore()
Defined with the attribute in getters
.
Accept "state" as first argument to encourage use of arrow functions
export const useStore = defineStore('count', {
state: () =>{
{
count: 1}},
getters: {
//方法一
doubleCount: (state) => {
return state.count * 2},
//方法二
doublePlusOne(): number {
return this.counter * 2 + 1 },
}
})
Pass the parameter to the getter
# 定义
getters: {
getUserId(state) =>{
const arr = state.foo.filter(....)
return (userId) => arr.find(id => userId == id)
}
}
#使用
{
{
getUserId(2)}}
When you do this, the getters are no longer cached , they are just functions that you call.
However, you can cache some results inside the getter itself
Ask the getters of other Stores
import {
useOtherStore} from './other-sotre'
getters: {
otherGetter(state) {
const otherStore = useOtherStore()
return state.localDate + otherStore.data
}
}
no setup()
import {
mapState } from 'pinia'
computed:{
...mapState(useCounterStroe, ['doubleCount'])
}
Actions
Equivalent to methods in components. Good for defining business logic
export const useStore = defineStore('main', {
actions: {
increment() {
this.count++},
async getApi() {
try{
let res = await post('url',options)
}catch{
}
}
},
})
Like getters , operations can this
be accessed via
actions
can be asynchronous
transfer
Actions are invoked like methods:
useStore.getApi()
does not apply to setup()
Action properties can mapActions()
be mapped to methods in components using
import {
mapActions } from 'pinia'
import {
getApi } from '../stores/useStore.js'
methods:{
...mapActions(getApi)
}
Subscribe to Actions
store.$onAction()
Subscribe to an action and its result using
const unsubscribe = someStore.$onAction(
({
name, // action 的名字
store, // store 实例
args, // 调用这个 action 的参数
after, // 在这个 action 执行完毕之后,执行这个函数
onError, // 在这个 action 抛出异常的时候,执行这个函数
}) => {
// 记录开始的时间变量
const startTime = Date.now()
// 这将在 `store` 上的操作执行之前触发
console.log(`Start "${
name}" with params [${
args.join(', ')}].`)
// 如果 action 成功并且完全运行后,after 将触发。
// 它将等待任何返回的 promise
after((result) => {
console.log(
`Finished "${
name}" after ${
Date.now() - startTime
}ms.\nResult: ${
result}.`
)
})
// 如果 action 抛出或返回 Promise.reject ,onError 将触发
onError((error) => {
console.warn(
`Failed "${
name}" after ${
Date.now() - startTime}ms.\nError: ${
error}.`
)
})
}
)
// 手动移除订阅
unsubscribe()
Triggered when/after the method is called
By default, action subscriptions are bound to the component that added them, and by default, action subscriptions are bound to the component that added them.
If you want to keep components after they are detached, pass true
as the second argument to the current component's detach action subscription
// 此订阅将在组件卸载后保留
someStore.$onAction(callback, true)