当前位置: 首页 > article >正文

vue原理分析(八)研究new Vue()中的initProxy

在Vue.prototype._init 中有一些init函数,今天我们来研究这些init函数

Vue.prototype._init = function (options) {
  ......
  {
    initProxy(vm);
  }
  ......
  initLifecycle(vm);
  initEvents(vm);
  initRender(vm);
  callHook$1(vm, 'beforeCreate', undefined, false /* setContext */);
  initInjections(vm); // resolve injections before data/props
  initState(vm);
  initProvide(vm); // resolve provide after data/props
  callHook$1(vm, 'created');
  ......
}

接下来我们逐步分析,先分析initProxy(vm)

Vue.prototype._init = function (options) {
  ......
  {
    initProxy(vm);
  }
  ......
}

查看initProxy源码

initProxy = function initProxy(vm) {
  if (hasProxy) {
      // determine which proxy handler to use
      const options = vm.$options;
      const handlers = options.render && options.render._withStripped ? getHandler : hasHandler;
      vm._renderProxy = new Proxy(vm, handlers);
  }
  else {
      vm._renderProxy = vm;
  }
};

通过判断hasProxy,来执行不同的处理逻辑

我们看下hasProxy的源码

const hasProxy = typeof Proxy !== 'undefined' && isNative(Proxy);

它的作用就是判断当前环境中Proxy是否可用

// determine which proxy handler to use
const options = vm.$options;
const handlers = options.render && options.render._withStripped ? getHandler : hasHandler;

回到代码中,如果当前环境存在Proxy,则执行块内的语句

三元表达式,如果options上存在render属性,且render属性上存在_withStripped属性,则proxy的traps(traps其实也就是自定义方法)采用getHandler方法,否则采用hasHandler方法

接下来看看getHandler和hasHandler方法

const getHandler = {
    get(target, key) {
        if (typeof key === 'string' && !(key in target)) {
            if (key in target.$data)
                warnReservedPrefix(target, key);
            else
                warnNonPresent(target, key);
        }
        return target[key];
    }
};
const hasHandler = {
    has(target, key) {
        const has = key in target;
        const isAllowed = allowedGlobals(key) ||
            (typeof key === 'string' &&
                key.charAt(0) === '_' &&
                !(key in target.$data));
        if (!has && !isAllowed) {
            if (key in target.$data)
                warnReservedPrefix(target, key);
            else
                warnNonPresent(target, key);
        }
        return has || !isAllowed;
    }
};

getHandler方法主要是针对读取代理对象的某个属性时进行的操作。当访问的属性不是string类型或者属性值在被代理的对象上不存在,则抛出错误提示,否则就返回该属性值

hasHandler方法的应用场景在于查看vm实例是否拥有某个属性—比如调用for in循环遍历vm实例属性时,会触发hasHandler方法。

回到initProxy代码中

if (hasProxy) {
    ...
    vm._renderProxy = new Proxy(vm, handlers)
  } else {
    vm._renderProxy = vm
  }
}

如果Proxy属性存在,则把包装后的vm属性赋值给_renderProxy属性值,否则把vm是实例本身赋值给_renderProxy属性。


http://www.kler.cn/news/304084.html

相关文章:

  • 集群聊天服务器项目【C++】(二)Json的简单使用
  • C++笔记---list
  • [QT] QT事件与事件重写
  • Spring扩展点系列-SmartInstantiationAwareBeanPostProcessor
  • 通过策略模式实现对象创建工厂
  • QMainWindow,调用exec()实现QDialog阻塞效果
  • HTTPS和HTTP区别是什么?
  • 【Python机器学习】循环神经网络(RNN)——利用Keras实现循环神经网络
  • 【XR】AR HUD
  • 交换机vlan配置实现
  • Java、python、php三个版本 抗震救灾物资管理系统 抗洪救灾物资分配系统 救援物资申请平台(源码、调试、LW、开题、PPT)
  • Android Framework(四)WMS-窗口显示流程——窗口创建与添加
  • TON的两种地址
  • Linux环境下运行 KF-GINS(GNSS+IMU松组合) 详细步骤
  • CGAL中的网格
  • PL/SQL 继承Oracle Database 的可靠性、安全性和可移植性
  • 初始爬虫1(补充)
  • 某讯/企鹅滑块验证码逆向(一)
  • 阿里云专业翻译api对接
  • OpenXR Monado创建跨进程通信通道 ipc_connect
  • SpringBoot常见面试题
  • 【前端】 flex布局详解
  • JavaScript StartsWith()方法
  • 从用户数据到区块链:Facebook如何利用去中心化技术
  • Postgresql 删除数组中的元素
  • Linux系统使用Docker安装DockerUI并实现远程管理本地容器无需公网IP
  • Prompt最佳实践|善用分隔符,让你的Prompt更清晰
  • 解决VScode中每次git push或者pull都需要重新输入账户名和密码问题
  • PL/SQL Developer工具的使用
  • 【数据结构初阶】队列接口实现及用队列实现栈超详解