入门指南
核心概念
服务端渲染
开发者指南
- Migrating from Vuex ≤4
- HMR (Hot Module Replacement)
- 测试存储商店
- Usage without setup()
- Composing Stores
- Migrating from 0.x (v1) to v2
API 手册
- API Documentation
- Module: pinia
- Module: @pinia/nuxt
- Module: @pinia/testing
- Enumeration: MutationType
- Interface: TestingOptions
- Interface: DefineSetupStoreOptions
- Interface: DefineStoreOptions
- Interface: DefineStoreOptionsBase
- Interface: DefineStoreOptionsInPlugin
- Interface: MapStoresCustomization
- Interface: Pinia
- Interface: PiniaCustomProperties
- Interface: PiniaCustomStateProperties
- Interface: PiniaPlugin
- Interface: PiniaPluginContext
- Interface: StoreDefinition
- Interface: StoreProperties
- Interface: SubscriptionCallbackMutationDirect
- Interface: SubscriptionCallbackMutationPatchFunction
- Interface: SubscriptionCallbackMutationPatchObject
- Interface: _StoreOnActionListenerContext
- Interface: _StoreWithState
- Interface: _SubscriptionCallbackMutationBase
- Interface: TestingPinia
Actions
Actions 相当于组件中的 methods。 它们可以使用 defineStore()
中的 actions
属性定义,并且它们非常适合定义业务逻辑:
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
}),
actions: {
// 因为我们依赖 `this`,所以我们不能使用箭头函数
increment() {
this.count++
},
randomizeCounter() {
this.count = Math.round(100 * Math.random())
},
},
})
与 getters 一样,操作可以通过 this
访问 whole store instance 并提供完整类型(和自动完成✨)支持。 与 getter 不同,actions
可以是异步的,您可以在任何 API 调用甚至其他操作的操作中await
! 这是使用 Mande 的示例。 请注意,只要您获得“Promise”,您使用的库并不重要,您甚至可以使用本机的“fetch”函数(仅限浏览器):
import { mande } from 'mande'
const api = mande('/api/users')
export const useUsers = defineStore('users', {
state: () => ({
userData: null,
// ...
}),
actions: {
async registerUser(login, password) {
try {
this.userData = await api.post({ login, password })
showTooltip(`Welcome back ${this.userData.name}!`)
} catch (error) {
showTooltip(error)
// 让表单组件显示错误
return error
}
},
},
})
你也可以完全自由地设置你想要的任何参数并返回任何东西。 调用动作时,一切都会自动推断!
Actions 像方法一样被调用:
jsexport default defineComponent({
setup() {
const store = useCounterStore()
// 将操作作为商店的方法调用
store.randomizeCounter()
return {}
},
})
访问其他商店的 Actions
要使用另一个商店,您可以直接在 Action 内部使用它:
jsimport { useAuthStore } from './auth-store'
export const useSettingsStore = defineStore('settings', {
state: () => ({
preferences: null,
// ...
}),
actions: {
async fetchUserPreferences() {
const auth = useAuthStore()
if (auth.isAuthenticated) {
this.preferences = await fetchPreferences()
} else {
throw new Error('User must be authenticated')
}
},
},
})
Usage with setup()
您可以直接调用任何操作作为 store 的方法:
jsexport default {
setup() {
const store = useCounterStore()
store.randomizeCounter()
},
}
使用选项式 API
对于以下示例,您可以假设已创建以下商店:
js// Example File Path:
// ./src/stores/counter.js
import { defineStore } from 'pinia',
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
}
}
})
With setup()
虽然 Composition API 并不适合所有人,但 setup()
钩子可以使在 Options API 中使用 Pinia 更容易。 不需要额外的地图辅助功能!
import { useCounterStore } from '../stores/counter'
export default {
setup() {
const counterStore = useCounterStore()
return { counterStore }
},
methods: {
incrementAndPrint() {
this.counterStore.increment()
console.log('New Count:', this.counterStore.count)
},
},
}
Without setup()
如果您根本不想使用 Composition API,可以使用 mapActions()
帮助器将操作属性映射为组件中的方法:
import { mapActions } from 'pinia'
import { useCounterStore } from '../stores/counter'
export default {
methods: {
// 允许访问组件内部的 this.increment()
// 与从 store.increment() 调用相同
...mapActions(useCounterStore, ['increment'])
// 与上面相同,但将其注册为 this.myOwnName()
...mapActions(useCounterStore, { myOwnName: 'increment' }),
},
}
订阅action
可以使用 store.$onAction()
观察动作及其结果。 传递给它的回调在操作本身之前执行。 after
处理承诺并允许您在操作解决后执行函数。 以类似的方式,onError
允许您在操作抛出或拒绝时执行函数。 这些对于在运行时跟踪错误很有用,类似于 Vue 文档中的这个提示。
这是一个在运行操作之前和它们解决/拒绝之后记录的示例。
jsconst unsubscribe = someStore.$onAction(
({
name, // 动作名称
store, // 存储实例,与 `someStore` 相同
args, // 传递给动作的参数数组
after, // 动作返回或解决后的钩子
onError, // 如果动作抛出或拒绝,则挂钩
}) => {
// 此特定操作调用的共享变量
const startTime = Date.now()
// 这将在 `store` 上的操作执行之前触发
console.log(`Start "${name}" with params [${args.join(', ')}].`)
// 如果操作成功并且完全运行后,这将触发。
// 它等待任何返回的承诺
after((result) => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
)
})
// 如果动作抛出或返回拒绝的承诺,这将触发
onError((error) => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
)
})
}
)
// 手动移除监听器
unsubscribe()
默认情况下,action subscriptions 绑定到添加它们的组件(如果商店位于组件的 setup()
内)。 意思是,当组件被卸载时,它们将被自动删除。 如果您还想在组件卸载后保留它们,请将 true
作为第二个参数传递给当前组件的 detach action subscription:
export default {
setup() {
const someStore = useSomeStore()
// 即使在卸载组件后,此订阅仍将保留
someStore.$onAction(callback, true)
// ...
},
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论