前言
【pinia源码】系列文章次要剖析pinia
的实现原理。该系列文章源码参考pinia v2.0.14
。
源码地址:https://github.com/vuejs/pinia
官网文档:https://pinia.vuejs.org
本篇文章将剖析storeToRefs
的实现。
应用
应用storeToRefs
创立一个对象,该对象蕴含store
中的所有state
、getter
及通过plugin
扩大的state
。
当应用store
的过程中,如果间接对store
进行解构,会毁坏数据的响应,所以pinia
提供了storeToRefs
用来进行解构。
import { storeToRefs } from 'pinia'import { useCounterStore } from '@/store/counterStore'export default { setup() { const counterStore = useCounterStore() // 能够解构actions const { increment } = counterStore const { count } = storeToRefs(counterStore) return { count, increment, } }}
storeToRefs
storeToRefs
接管一个store
参数。
export function storeToRefs<SS extends StoreGeneric>( store: SS): ToRefs< StoreState<SS> & StoreGetters<SS> & PiniaCustomStateProperties<StoreState<SS>>> { // See https://github.com/vuejs/pinia/issues/852 // It's easier to just use toRefs() even if it includes more stuff if (isVue2) { // 如果是vue2间接返回toRefs(store),只管其中蕴含很多methods return toRefs(store) } else { // 非vue2环境,会过滤store中的非ref或reactive对象 // store的原始对象 store = toRaw(store) const refs = {} as ToRefs< StoreState<SS> & StoreGetters<SS> & PiniaCustomStateProperties<StoreState<SS>> > for (const key in store) { const value = store[key] if (isRef(value) || isReactive(value)) { // 应用toRef获取一个新的ref refs[key] = toRef(store, key) } } return refs }}
首先判断是否为vue2
环境,如果是vue2
环境,间接应用toRefs
将store
转换为一个一般对象;如果不是vue2
环境,首先获取store
的原始对象,而后遍历原始对象的键值,在遍历过程中,只会解决ref
(ref
类型的值包含store
中的state
与getter
,getter
会被转为计算属性)与reactive
类型的值,对于符合条件的值,会将这些值转为ref
类型的值,而后将其复制到一个新的对象中refs
中,最初返回refs
。