Vue3.0 响应式系统(五)toRaw markRaw

这篇文章看看Vue3.0给我们提供的这两个方法,toRaw方法是把被reactive或readonly后的Proxy对象转换为原来的target对象,而markRaw则直接让target不能被reactive或readonly。

先看看toRaw怎么用,

       setup(){       
          let obj = {
            msg: 'hello',
            student: {
              name: 'xiaoliu',
              age: 20
            }
          }
          let reactiveObj = reactive(obj)
          let state = toRaw(reactiveObj)    
          return {state}
        }

用法很简单,看看转换前后Proxy对象和target对象:

上图是进行reactive后的Proxy对象,看看对其toRaw后,

toRaw后,Proxy对象又被转换回去了。还记得在调用createReactiveObject进行Proxy时,用WeakMap数据结构把target和Proxy对象联系起来了:proxyMap.set(target, proxy)。

toRaw就通过Proxy把target给提取出来,看看具体怎么做的:

export function toRaw<T>(observed: T): T {
  return (
    (observed && toRaw((observed as Target)[ReactiveFlags.RAW])) || observed
  )
}


function createGetter(isReadonly = false, shallow = false) {
  return function get(target: Target, key: string | symbol, receiver: object) {
    if (key === ReactiveFlags.IS_REACTIVE) {
      return !isReadonly
    } else if (key === ReactiveFlags.IS_READONLY) {
      return isReadonly
    } else if (
      key === ReactiveFlags.RAW &&
      receiver === (isReadonly ? readonlyMap : reactiveMap).get(target)
    ) {
      //在这里把通过比较Proxy,把target给找出来
      return target
    }

如果传给toRaw的参数不是Proxy对象则原样返回。

接下来看看markRaw方法,

export function markRaw<T extends object>(value: T): T {
  //给target增加一个ReactiveFlags.SKIP属性
  def(value, ReactiveFlags.SKIP, true)
  return value
}

export const def = (obj: object, key: string | symbol, value: any) => {
  Object.defineProperty(obj, key, {
    configurable: true,
    enumerable: false,
    value
  })
}

function getTargetType(value: Target) {
  //判断如果target有ReactiveFlags.SKIP属性,则直接判断不在可以进行reactive的白名单中,从而不能进行reactive
  return value[ReactiveFlags.SKIP] || !Object.isExtensible(value)
    ? TargetType.INVALID
    : targetTypeMap(toRawType(value))
}

markRaw通过增加一个属性标志ReactiveFlags.SKIP,来判断是否能进行reactive,非常简单,不再进行表述了。

toRaw在实际的业务开发中感觉用的频次应该比较低。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值