time: 2022-04-27 16:45:43
author: heyunjiang
最近在做 vue3 项目,使用到了 pinia 做全局状态共享,如下操作步骤
import { defineStore } from 'pinia'
import { reactive } from 'vue'
export const useUploadStore = defineStore('upload', () => {
const uploading = reactive({})
return {
uploading
}
})
import { createApp } from 'vue'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
import { storeToRefs } from 'pinia'
import { useUploadStore } from '@/store/upload'
const { uploading } = storeToRefs(useUploadStore())
uploading.value.hello = 'world'
import { useUploadStore } from ‘@/store/upload’ const { uploading } = storeToRefs(useUploadStore()) const uploadingKeys = computed(() => Object.keys(uploading.value)) ```
相较于 vuex,pinia 有如下优点
但是也产生了疑问
router 对象是存储在内存中,通过 $router 或 useRouter 访问
同 router 一样,核心使用 vue3 provide + inject api 实现
app.use(createPinia())
时创建了 pinia 对象,app 通过 provide 保存了对该对象的引用 app.provide(piniaSymbol, pinia)
defineStore
定义好的 store,在 setup 执行过程中会调用 store 的初始化流程:
执行 inject(piniaSymbol)
加载 pinia 对象和 createSetupStore(id, setup, options, pinia)
初始化 storeprovide/inject 原理是使用 appContext.provide 对象保存状态数据,共享响应式对象(ref, reactive) 时,子组件获取就是响应式的
createRouter | createPinia
生成的对象绑定到 app 上,使用 app.provide + useRouter | useStore 提供 composition api 使用方式,
同时也提供了 app.config.globalProperties 绑定全局 $pinia or $router 的 vue option api 使用一个 app 对象只使用一个 pinia | router 对象 |