• vue源码解析之选项合并(一)


    选项 el、propsData 的合并策略

      接下来看看选项合并有哪些策略

    /**
     * Options with restrictions
     */
    if (process.env.NODE_ENV !== 'production') {
      strats.el = strats.propsData = function (parent, child, vm, key) {
        if (!vm) {
          warn(
            `option "${key}" can only be used during instance ` +
            'creation with the `new` keyword.'
          )
        }
        return defaultStrat(parent, child)
      }
    }
    

    在非生产环境下在 strats 策略对象上添加两个策略分别是 el 和 propsData,两个属性值都是函数

      这两个策略函数是用来合并 el 选项和 propsData 选项的。

    if (!vm) {
          warn(
            `option "${key}" can only be used during instance ` +
            'creation with the `new` keyword.'
          )
        }
    

      if判断是否有传递vm,如果没有就会警告,提示你 el 选项或者 propsData 选项只能在使用 new 操作符创建实例的时候可用

          如果没有vm,则说明是子组件选项?为什么这样说?

          首先我们要搞清楚策略函数中的 vm 参数是哪里来的:看看vue源码中的mergeField 函数

    function mergeField (key) {
        var strat = strats[key] || defaultStrat;
        options[key] = strat(parent[key], child[key], vm, key);
      }
    

      第三个参数vm就是我们策略中使用的vm,

           在看看_init 方法:

    // _init 方法中调用 mergeOptions 函数,第三个参数是 Vue 实例
    vm.$options = mergeOptions(
      resolveConstructorOptions(vm.constructor),
      options || {},
      vm
    )
    

     通过_init方法可以看出,策略函数中的 vm 来自于 mergeOptions 函数的第三个参数,

     mergeOptions函数传第三个参数,策略中就拿不到vm参数,除了_init方法中调用了mergeOptions函数,其他很多地方都调用了

       Vue.extend方法中也调用了mergeoptions函数

    Sub.options = mergeOptions(
      Super.options,
      extendOptions
    )
    

      此时在Vue.extend方法中调用了mergeOptions函数,但是没有传第三个参数vm,所以在策略中无法拿到vm,

           就能得出mergeOptions函数是在实例化时使用new操作符走_init方法还是继承时走的Vue.extend方法

          子组件是通过实例化子类完成的,子类是通过Vue.extend方法创造出来的,

    综上得出可以通过if(!vm)判断是否是子组件

      接下来回到开头:

    return defaultStrat(parent, child)
    

      调用了defaultStrat方法传入两个参数分别是父选项和子选项。

           defaultStrat方法有什么作用呢?就像它的名字一样,默认的策略,或许你还不太懂,我们来看看defaultStrat方法吧

    const defaultStrat = function (parentVal: any, childVal: any): any {
      return childVal === undefined
        ? parentVal
        : childVal  //只要子选项不是 undefined 那么就是用子选项,否则使用父选项。
    }
    

      

    strats.el 和 strats.propsData 这两个策略函数是只有在非生产环境才有的,在生产环境下访问这两个函数将会得到 undefined,那这个时候 mergeField 函数的第一句代码就起作用了:

    // 当一个选项没有对应的策略函数时,使用默认策略
    const strat = strats[key] || defaultStrat
    

    所以在生产环境将直接使用默认的策略函数 defaultStrat 来处理 el 和 propsData 这两个选项

    //上班划水写博客,下班时间到了 溜了溜了。。。

    //下次更新 选项data合并策略

  • 相关阅读:
    Cocos2D学习笔记(1)- 常用的类
    C++头文件的重复定义错误处理
    python3中的sort和sorted函数
    numpy提供的快速的元素级数组函数
    HDU 1180 诡异的楼梯(BFS)
    POJ 1020 Anniversary Cake(DFS)
    POJ 1564 Sum It Up(DFS)
    POJ 1190 生日蛋糕(DFS)
    HDU 1026 Ignatius and the Princess I(BFS+优先队列)
    HDU 1172 猜数字(DFS)
  • 原文地址:https://www.cnblogs.com/xweizi/p/10538870.html
Copyright © 2020-2023  润新知