vue2.0 源码解析 initProxy 初始化代理

源代码

目录结构 src\core\instance\proxy.js

/* not type checking this file because flow doesn't play well with Proxy */

import config from 'core/config'
import { warn, makeMap, isNative } from '../util/index'

let initProxy

if (process.env.NODE_ENV !== 'production') {
  const allowedGlobals = makeMap(
    'Infinity,undefined,NaN,isFinite,isNaN,' +
    'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
    'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,' +
    'require' // for Webpack/Browserify
  )
  // js中可以全局访问的 


  const warnNonPresent = (target, key) => {
    warn(
      `Property or method "${key}" is not defined on the instance but ` +
      'referenced during render. Make sure that this property is reactive, ' +
      'either in the data option, or for class-based components, by ' +
      'initializing the property. ' +
      'See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.',
      target
    )
  }

  const warnReservedPrefix = (target, key) => {
    warn(
      `Property "${key}" must be accessed with "$data.${key}" because ` +
      'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
      'prevent conflicts with Vue internals. ' +
      'See: https://vuejs.org/v2/api/#data',
      target
    )
  }

  const hasProxy =
    typeof Proxy !== 'undefined' && isNative(Proxy)
  // 判断Proxy 是否存在 
  if (hasProxy) {
    debugger
    const isBuiltInModifier = makeMap('stop,prevent,self,ctrl,shift,alt,meta,exact')
    // 用makeMap函数来修饰是否是内置修饰符
    config.keyCodes = new Proxy(config.keyCodes, {
      set(target, key, value) {
        // config.keyCodes 设置set 代理,防止内置修饰符被覆盖
        if (isBuiltInModifier(key)) {
          warn(`Avoid overwriting built-in modifier in config.keyCodes: .${key}`)
          return false
        } else {
          target[key] = value
          return true
        }
      }
    })
  }

  const hasHandler = {
    has(target, key) {
      debugger
      const has = key in target// 此处的target是 vue实例 key in target表示是否是vue实例上的属性
      // target 要代理的对象,此处时 vue ,key 在外部操作时访问的属性
      console.log("allowedGlobals", allowedGlobals, target.$data)
      const isAllowed = allowedGlobals(key) ||
        (typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data))
      /* 
        allowedGlobals 
          在模板引擎里,有一些属性vm没有进行代理,但是也能使用,如 number 等
          _ 下划线开头的属性 vue的内置属性
          不在data里定义的属性

      
      */
      if (!has && !isAllowed) {
        // 不是vue 实例上的属性 并且 也不是内置属性 是data上的属性
        debugger
        if (key in target.$data) warnReservedPrefix(target, key)
        else warnNonPresent(target, key)
      }
      return has || !isAllowed
    }
  }

  const getHandler = {
    get(target, key) {
      debugger
      console.log("target.$data", target.$data)
      if (typeof key === 'string' && !(key in target)) {
        //检测data 属性是不是  $. _开头
        if (key in target.$data) {
          warnReservedPrefix(target, key)
        }
        else {
          warnNonPresent(target, key)
        }
      }
      return target[key]
    }
  }

  initProxy = function initProxy(vm) {
    debugger
    if (hasProxy) {
      //判断是否支持  Proxy代理 
      // determine which proxy handler to use
      const options = vm.$options
      // vm.$options 表示传入的选项
      const handlers = options.render && options.render._withStripped
        ? getHandler
        : hasHandler
      vm._renderProxy = new Proxy(vm, handlers)
    } else {
      vm._renderProxy = vm
    }
  }
}

export { initProxy }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值