Pinia (试验)
声明
@vue-mini/pinia
目前处于试验阶段,这表示它还没有经过大规模的生产验证。不过它的质量是可靠的,你可以将其用于生产环境。我们预计会在很少甚至零代码改动的情况下结束试验。
Pinia 是 Vue.js 的官方状态管理库。Vue Mini 将其移植了过来,移植版本与官方版本有着一模一样的 API 和能力,但是也有一些差异。关于 Pinia 的具体使用方式以及 API 请参考 Pinia 官方文档,这篇文档只会着重说明二者的不同之处。
安装
$ npm install @vue-mini/pinia
$ pnpm install @vue-mini/pinia
$ yarn add @vue-mini/pinia
$ bun add @vue-mini/pinia
初始化
// pinia.js
import { createPinia } from '@vue-mini/pinia'
export const pinia = createPinia()
// app.js
import { createApp } from '@vue-mini/core'
import './pinia'
createApp(() => {
// ...
})
在 Vue.js 中初始化 Pinia 你需要将 Pinia 实例作为插件传递给 Vue.js 的 App 实例,也就是:app.use(pinia)
,在 Vue Mini 中没有这个步骤。
定义 Store
import { ref, computed } from '@vue-mini/core'
import { defineStore } from '@vue-mini/pinia'
export const useStore = defineStore('main', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
const increment = () => {
count.value++
}
return { count, double, increment }
})
@vue-mini/pinia
仅支持 Setup Store,不支持 Option Store。又因为 Store 实例的 $reset
方法仅针对 Option Store 有效,所以 @vue-mini/pinia
的 Store 实例没有 $reset
方法。如果你有需要可以自行实现:
import { ref, computed } from '@vue-mini/core'
import { defineStore } from '@vue-mini/pinia'
export const useStore = defineStore('main', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
const increment = () => {
count.value++
}
const $reset = () => {
count.value = 0
}
return { count, double, increment, $reset }
})
使用 Store
import { defineComponent } from '@vue-mini/core'
import { storeToRefs } from '@vue-mini/pinia'
import { useStore } from '../../store'
defineComponent(() => {
const store = useStore()
const { increment } = store
const { count, double } = storeToRefs(store)
// 不可以这样写:
// return { store }
// 也不可以这样写(会丢失响应性):
// const { count, double } = store
// return { count, double }
// 或者:
// return { count: store.count, double: store.double }
return {
count,
double,
increment,
}
})
在 Vue.js 中你可以将整个 store 暴露给模版,然后在模版中使用 store.xxx
,这很方便。但是很遗憾在小程序中你不能这样干,这是因为小程序模版运行在一个独立的线程中,与 JS 并不共享同一个上下文。所以你需要逐个的将 store 的状态和方法暴露给小程序模板。
然后因为从 store 中获取原始值会导致响应性丢失,所以你需要使用 storeToRefs()
以保留响应性,如上面的代码所示。
插件
@vue-mini/pinia
也支持自定义插件,插件的编写和使用与 Pinia 一样。你可以根据需要编写自己的插件,或者选择已有的插件使用。例如我写了一个状态持久化插件:pinia-mini-plugin-persistor,使用这个插件可以自动的持久化存储并恢复 Store 状态。
import { ref, computed } from '@vue-mini/core'
import { createPinia } from '@vue-mini/pinia'
import persistor from 'pinia-mini-plugin-persistor'
export const pinia = createPinia()
pinia.use(persistor)
export const useStore = defineStore(
'main',
() => {
const count = ref(0)
const double = computed(() => count.value * 2)
const increment = () => {
count.value++
}
return { count, double, increment }
},
{
persist: true,
},
)