【pinia源码】系列文章
-
【pinia源码】一、createPinia源码解析
-
【pinia源码】二、defineStore源码解析
- 【pinia源码】三、storeToRefs源码解析
-
【pinia源码】四、mapHelper API源码解析
前言
【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
。