组合 Store
组合 Store 指的是 Store 之间相互使用,Pinia 支持这种方式。需要遵循一条规则
如果 **两个或多个 Store 相互使用**,它们不能通过 Getter 或 Action 创建无限循环。它们不能在 setup 函数中 **同时** 直接读取彼此的状态
js
const useX = defineStore('x', () => {
const y = useY()
// ❌ This is not possible because y also tries to read x.name
y.name
function doSomething() {
// ✅ Read y properties in computed or actions
const yName = y.name
// ...
}
return {
name: ref('I am X'),
}
})
const useY = defineStore('y', () => {
const x = useX()
// ❌ This is not possible because x also tries to read y.name
x.name
function doSomething() {
// ✅ Read x properties in computed or actions
const xName = x.name
// ...
}
return {
name: ref('I am Y'),
}
})
嵌套 Store
请注意,如果一个 Store 使用另一个 Store,你可以在 Action 和 Getter 中直接导入并调用 useStore()
函数。然后,你可以像在 Vue 组件中一样与 Store 进行交互。请参阅 共享 Getter 和 共享 Action。
对于 setup Store,你只需在 Store 函数的 **顶部** 使用其中一个 Store
ts
import { useUserStore } from './user'
export const useCartStore = defineStore('cart', () => {
const user = useUserStore()
const list = ref([])
const summary = computed(() => {
return `Hi ${user.name}, you have ${list.value.length} items in your cart. It costs ${price.value}.`
})
function purchase() {
return apiPurchase(user.id, this.list)
}
return { summary, purchase }
})
共享 Getter
你只需在 Getter 中调用 useOtherStore()
js
import { defineStore } from 'pinia'
import { useUserStore } from './user'
export const useCartStore = defineStore('cart', {
getters: {
summary(state) {
const user = useUserStore()
return `Hi ${user.name}, you have ${state.list.length} items in your cart. It costs ${state.price}.`
},
},
})
共享 Action
Action 也是如此
js
import { defineStore } from 'pinia'
import { useUserStore } from './user'
export const useCartStore = defineStore('cart', {
actions: {
async orderCart() {
const user = useUserStore()
try {
await apiOrderCart(user.token, this.items)
// another action
this.emptyCart()
} catch (err) {
displayError(err)
}
},
},
})
由于 Action 可以是异步的,请确保 **所有 useStore()
调用都出现在任何 await
之前**。否则,这可能会导致在 SSR 应用程序 中使用错误的 Pinia 实例
js
import { defineStore } from 'pinia'
import { useUserStore } from './user'
export const useCartStore = defineStore('cart', {
actions: {
async orderCart() {
// ✅ call at the top of the action before any `await`
const user = useUserStore()
try {
await apiOrderCart(user.token, this.items)
// ❌ called after an `await` statement
const otherStore = useOtherStore()
// another action
this.emptyCart()
} catch (err) {
displayError(err)
}
},
},
})