共计 1375 个字符,预计需要花费 4 分钟才能阅读完成。
前言
【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
。
正文完