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

vue原理分析(十二)研究new Vue()中的 initInjections

在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');
  ......
}


上一篇中已经研究了 initRender ,今天我们往下研究

initInjections(vm);
function initInjections(vm) {
    const result = resolveInject(vm.$options.inject, vm);
    if (result) {
        toggleObserving(false);
        Object.keys(result).forEach(key => {
            /* istanbul ignore else */
            {
                defineReactive(vm, key, result[key], () => {
                    warn$2(`Avoid mutating an injected value directly since the changes will be ` +
                        `overwritten whenever the provided component re-renders. ` +
                        `injection being mutated: "${key}"`, vm);
                });
            }
        });
        toggleObserving(true);
    }
}

我们逐步来解析代码

function initInjections(vm) {
  const result = resolveInject(vm.$options.inject, vm);
  ......
}


这里是解析vm.$options.inject,返回解析后的对象

function resolveInject(inject, vm) {
    if (inject) {
        // inject is :any because flow is not smart enough to figure out cached
        // inject 是 any 类型,因为flow不够智能,不能算出类型
        // 创建一个空对象用于存放结果
        const result = Object.create(null);
        // 获取 key 名
        // 如果支持hasSymbol ,则用 Reflect.ownKeys(inject) 否则用 Object.keys(inject)
        const keys = hasSymbol ? Reflect.ownKeys(inject) : Object.keys(inject);         
        for (let i = 0; i < keys.length; i++) {
            const key = keys[i];
            // #6574 in case the inject object is observed...
            // 如果是observed,则跳过
            if (key === '__ob__')
                continue;
            const provideKey = inject[key].from;
            if (provideKey in vm._provided) {
                // 向父级_provided属性遍历查找属性值
                // 因为父级组件使用provide选项注入数据时会将注入的数据存入自身实例的_provided属    
                result[key] = vm._provided[provideKey];
            }
            else if ('default' in inject[key]) {
                // 当前的数据key存在默认值即default属性
                const provideDefault = inject[key].default;
                result[key] = isFunction(provideDefault)
                    ? provideDefault.call(vm)
                    : provideDefault;
            }
            else {
                warn$2(`Injection "${key}" not found`, vm);
            }
        }
        return result;
    }
}
function initInjections(vm) {
    ......
    if (result) {
        toggleObserving(false);
        ......
        toggleObserving(true);
    }
}

这两个toggleObserving是切换观察模式

function initInjections(vm) {
    ......
    if (result) {
        ......
        Object.keys(result).forEach(key => {
            /* istanbul ignore else */
            {
                defineReactive(vm, key, result[key], () => {
                    warn$2(`Avoid mutating an injected value directly since the changes will be ` +
                        `overwritten whenever the provided component re-renders. ` +
                        `injection being mutated: "${key}"`, vm);
                });
            }
        });
        ......
    }
}

用foreach循环对keys中的每一个key做defineReactive处理


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

相关文章:

  • MVVM 基础
  • 计算机科学基础 -- 超流水线
  • cross-plateform 跨平台应用程序-04-React Native 介绍
  • 缓存预热/雪崩/穿透/击穿
  • 基于Python实现一个庆祝中秋节的小程序
  • C#笔记7 网络通信抽象,Socket类的介绍和简单使用
  • 逆向工程 反编译 C# net core
  • 布偶猫应该喂什么猫罐头:交响乐金罐、希喂、尾巴生活测评
  • 复现PointNext代码
  • 【Qt笔记】QGroupBox控件详解
  • 搭建一个大模型API服务
  • 代码随想录打卡Day29
  • 安宝特案例 | AR如何大幅提升IC封装厂检测效率?
  • C++20标准对线程库的改进:更安全、更高效的并发编程
  • 基于SpringBoot+Vue的民宿管理系统
  • pip install “git+https://xxx“报错error: subprocess-exited-with-error
  • Rust:深入浅出说一说 Error 类型
  • Oracle数据库中的Oracle Real Application Clusters是什么
  • SpringBoot动态SQL
  • 第15-02章:理解Class类并获取Class实例
  • leetcode1.两数之和
  • 编写XBOX控制器实现鼠标键盘输入
  • Python | Leetcode Python题解之第400题第N位数字
  • Iceberg与SparkSQL写操作整合
  • 【IP协议】IP协议报头结构(上)
  • Entity Framework (EF)框架中三种主要的数据加载策略
  • 反序列化漏洞练习1
  • Java实现简易计算器功能(idea)
  • Node.js发票识别接口助力企业实现发票的精准高效管理
  • golang学习笔记10——golang 的 Gin 框架,快速构建高效 Web 应用