这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战
pinia 在我的文章中已经是一个熟悉的面孔了,本人的项目也都全部都向pinia进行了迁移。
主要原因就是简单易上手,源码也容易懂。
如果不了解的可以看看它的文档:放一些部分的链接
上文回顾
回顾一下pinia插件的用法
const pinia = createPinia()
// give the plugin to pinia
pinia.use(SecretPiniaPlugin)
创建plugin
function testPlugin(ctx) {
// do something
return {...}
}
typescript
如果你看过上面的文章或文档,那么你完全可以用javascript书写一个pinia插件了。
但是pinia的初衷就是更好的结合typescript,所以我们书写ts plugin需要注意以下几点
Typing plugins
import { PiniaPluginContext } from 'pinia'
export function myPiniaPlugin(context: PiniaPluginContext) {
// ...
}
为了更好的类型推导和约束,pinia导出了一个规范的pinia上下文,我们需要对插件的第一个参数进行定义。
Typing new store properties
import 'pinia'
declare module 'pinia' {
export interface PiniaCustomProperties {
// by using a setter we can allow both strings and refs
set hello(value: string | Ref<string>)
get hello(): string
// you can define simpler values too
simpleNumber: number
}
}
当我们给pinia的store新增自定义属性时,我们需要同时对pinia的类型文档(.d.ts)同时增加类型,方便给pinia的推导和智能提示。
pinia.use(({ store }) => {
store.hello = 'Hola'
store.hello = ref('Hola')
store.number = Math.random()
// @ts-expect-error: we haven't typed this correctly
store.number = ref(Math.random())
})
于是就可以安全又方便的写出对象属性,对错误的提前约束能力
Typing new creation options
当我们需要对pinia的store的创建新增选项时
import { defineStore } from 'pinia'
// useStore could be anything like useUser, useCart
// the first argument is a unique id of the store across your application
export const useStore = defineStore('main', {
// other options...
// 这里来新增选项
})
当我们使用defineStore()创建store时,我们应该extend DefineStoreOptionsBase, 与PiniaCustomProperties不同的是,它只公开两个泛型:State 和 Store 类型,允许我们限制可以定义的内容。
import 'pinia'
declare module 'pinia' {
export interface DefineStoreOptionsBase<S, Store> {
// allow defining a number of ms for any of the actions
debounce?: Partial<Record<keyof StoreActions<Store>, number>>
}
}
总结
上面应该总结了pinia插件的所有注意事项,若有遗漏,详情还多多翻阅官方文档。
或许你可以亲手尝试 pinia插件玩玩。