前言【pinia源码】系列文章主要分析pinia的实现原理。本系列文章源码参考piniav2.0.14。源码地址:https://github.com/vuejs/pinia官方文档:https://pinia.vuejs.org本文将分析storeToRefs的实现。使用storeToRefs创建一个对象,该对象包含存储中插件扩展的所有状态、getter和状态。在使用store的时候,如果直接解构store,数据响应会被销毁,所以pinia提供了storeToRefs用于解构。import{storeToRefs}from'pinia'import{useCounterStore}from'@/store/counterStore'exportdefault{setup(){constcounterStore=useCounterStore()//可以解构动作const{increment}=counterStoreconst{count}=storeToRefs(counterStore)return{count,increment,}}}storeToRefsstoreToRefs接收一个存储参数。exportfunctionstoreToRefs(store:SS):ToRefs&StoreGetters&PiniaCustomStateProperties>>{//参见https://github.com/vuejs/pinia/issues/852//只使用toRefs()更容易,即使它包含更多的东西if(isVue2){//如果vue2直接返回toRefs(store),尽管它包含很多方法returntoRefs(store)}else{//非vue2环境,会过滤store中的non-ref或reactive对象//store的原始对象store=toRaw(store)constrefs={}asToRefs&StoreGetters&PiniaCustomStateProperties>>>for(constkeyinstore){constvalue=store[key]if(isRef(value)||isReactive(value)){//使用toRef获取新的refrefs[key]=toRef(store,key)}}returnrefs}}首先判断是否是vue2环境,如果是vue2环境,直接使用toRefs将store转为普通对象;如果不是vue2环境,先获取store的原始对象,然后遍历原始对象的key遍历过程中,只会处理ref(ref类型的值包括store中的state和getter,getter会转化为computed属性)和reactive类型的值。对于符合条件的值,这些值会被转换成ref类型的值,然后复制到refs中一个新的对象,最后返回refs