【pinia源码】三、storeToRefs源码解析
前言
【pinia源码】系列文章主要分析pinia的实现原理。该系列文章源码参考pinia v2.0.14。
源码地址:https://github.com/vuejs/pinia
本篇文章将分析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。
转载自:https://segmentfault.com/a/1190000042003924