Skip to content

从pinia基础的用法,看源码的实现。

如何理解Vue3里的EffectScope? - 知乎

一切的开始 createPinia

pinia中的effectScope是什么?

Vue 3.2版本引入了新的 Effect scope API,用于创建一个effect Scope对象,该对象可以捕获在其中创建的反应性效果(例如computed 或 watchers),以便可以将这些效果放在一起并轻松处理它们。它可以更轻松地在组件上下文之外使用 Vue 的响应式 API,同时也在组件之内解锁了多种高级用例!

createPinia方法返回pinia对象, pinia对象内部有Install方法,用于在vue中注册。该install方法会把pinia对象通过vue的provide挂载在vue实例下;

javascript
export function createPinia(): Pinia {

  // ......
  const pinia: Pinia = markRaw({
    install(app: App) {
      // this allows calling useStore() outside of a component setup after
      // installing pinia's plugin
      setActivePinia(pinia)
      if (!isVue2) {
        pinia._a = app
        app.provide(piniaSymbol, pinia)
        app.config.globalProperties.$pinia = pinia
        /* istanbul ignore else */
        if (USE_DEVTOOLS) {
          registerPiniaDevtools(app, pinia)
        }
        toBeInstalled.forEach((plugin) => _p.push(plugin))
        toBeInstalled = []
      }
    },
    // ......
  })
  // ......

  return pinia
}

definestore发生了什么

definestore函数返回了useStore函数,实际执行usestore函数时,才会进行核心store的创建逻辑。

useStore

useStore函数

createSetupStore

createSetupStore函数是核心的处理store的逻辑,该函数代码主要做了一下事:

  1. 注册了$onAction$subscribe等API
  2. 对state、action等进行包装处理,包括一些边界值,支持回调等特性。

API

reset

reset方法主要是利用闭包,来保留初始的state,从而可以随时重置state

javascript
/**
 * $reset 
 * 只有 选项式 构建的才可以使用此方法,
 * 因为 state: () => ({count: 1}) 是一个函数,只要重新调用就可以获取原始值,
 * 而 组合式 构建的话 state 以 ref() 的形式实现,无法获取原始值。
 */
const $reset = isOptionsStore
    ? function $reset(this: _StoreWithState<Id, S, G, A>) {
      // 利用闭包,保留下options函数
      const { state } = options as DefineStoreOptions<Id, S, G, A>
      const newState = state ? state() : {}
      // we use a patch to group all changes into one single subscription
      this.$patch(($state) => {
        assign($state, newState)
      })
    }
    : /* istanbul ignore next */
    __DEV__
      ? () => {
        throw new Error(
          `🍍: Store "${$id}" is built using the setup syntax and does not implement $reset().`
        )
      }
      : noop