zoukankan      html  css  js  c++  java
  • vue源码解析之选项合并(二)

    选项 data 的合并策略

    我们跳过mergeData 以及 mergeDataOrFn,我们暂且不关注这两个函数的作用。暂且跳过继续看下面的代码:

    strats.data = function (
      parentVal: any,
      childVal: any,
      vm?: Component
    ): ?Function {
      if (!vm) {
        if (childVal && typeof childVal !== 'function') {
          process.env.NODE_ENV !== 'production' && warn(
            'The "data" option should be a function ' +
            'that returns a per-instance value in component ' +
            'definitions.',
            vm
          )
    
          return parentVal
        }
        return mergeDataOrFn(parentVal, childVal)
      }
    
      return mergeDataOrFn(parentVal, childVal, vm)
    }

    在strats策略对象上面添加了一个data策略函数,进行选项data的策略合并

    if (!vm) {}如同上一篇文章介绍一样 用来判断是否是子组件选项,
    如果是子组件选项
    return mergeDataOrFn(parentVal, childVal)
    如果不是 return mergeDataOrFn(parentVal, childVal, vm)
    再来看看if判断里面的内容:
    if (childVal && typeof childVal !== 'function') {}
    

      判断是否又子组件的data,并且检测是否是一个function,如果不是函数则会警告,并且返回parentVal

            如果childval是函数 则会返回mergeDataOrFn(parentVal, childVal) 执行结果

           后面就不用说了, 如果又vm 就执行mergeDataOrFn(parentVal, childVal, vm)

    接下来我们看看一直调用的mergeDataOrFn函数是什么:

    /**
     * Data
     */
    export function mergeDataOrFn (
      parentVal: any,
      childVal: any,
      vm?: Component
    ): ?Function {
      if (!vm) {
        // in a Vue.extend merge, both should be functions
        if (!childVal) {
          return parentVal
        }
        if (!parentVal) {
          return childVal
        }
        // when parentVal & childVal are both present,
        // we need to return a function that returns the
        // merged result of both functions... no need to
        // check if parentVal is a function here because
        // it has to be a function to pass previous merges.
        return function mergedDataFn () {
          return mergeData(
            typeof childVal === 'function' ? childVal.call(this, this) : childVal,
            typeof parentVal === 'function' ? parentVal.call(this, this) : parentVal
          )
        }
      } else {
        return function mergedInstanceDataFn () {
          // instance merge
          const instanceData = typeof childVal === 'function'
            ? childVal.call(vm, vm)
            : childVal
          const defaultData = typeof parentVal === 'function'
            ? parentVal.call(vm, vm)
            : parentVal
          if (instanceData) {
            return mergeData(instanceData, defaultData)
          } else {
            return defaultData
          }
        }
      }
    }
    

      整体的也是和之前的几个函数一样 首先对vm的判断,其中就mergeData函数需要介绍下,看下mergeData源码,这个函数是用来干嘛的

    /**
     * Helper that recursively merges two data objects together.
     */
    function mergeData (to: Object, from: ?Object): Object {
      // 没有 from 直接返回 to
      if (!from) return to
      let key, toVal, fromVal
      const keys = Object.keys(from)
      // 遍历 from 的 key
      for (let i = 0; i < keys.length; i++) {
        key = keys[i]
        toVal = to[key]
        fromVal = from[key]
        // 如果 from 对象中的 key 不在 to 对象中,则使用 set 函数为 to 对象设置 key 及相应的值
        if (!hasOwn(to, key)) {
          set(to, key, fromVal)
        // 如果 from 对象中的 key 也在 to 对象中,且这两个属性的值都是纯对象则递归进行深度合并
        } else if (isPlainObject(toVal) && isPlainObject(fromVal)) {
          mergeData(toVal, fromVal)
        }
        // 其他情况什么都不做
      }
      return to
    }
    

     接收两个参数,to,from;

       根据调用传参  to 对应的是 childVal 产生的纯对象,from 对应 parentVal 产生的纯对象

      这个函数作用就是:将 from 对象的属性混合到 to 对象中,也可以说是将 parentVal 对象的属性混合到 childVal 中,最后返回的是处理后的 childVal 对象。

     合并阶段 strats.data 将被处理成一个函数,但是这个函数并没有被执行,而是到了后面初始化的阶段才执行的,

    重点:!!!!!!!!!!!

    mergeData 函数只有在初始化的时候才会执行,进行数据合并;

     Vue 的初始化的时候, inject 和 props 这两个选项的初始化是先于 data 选项的,这就保证了我们能够使用 props 初始化 data 中的数据

  • 相关阅读:
    STL源码剖析之_allocate函数
    PAT 1018. Public Bike Management
    PAT 1016. Phone Bills
    PAT 1012. The Best Rank
    PAT 1014. Waiting in Line
    PAT 1026. Table Tennis
    PAT 1017. Queueing at Bank
    STL源码剖析之list的sort函数实现
    吃到鸡蛋好吃,看看是哪只母鸡下的蛋:好用的Sqlite3
    cJSON
  • 原文地址:https://www.cnblogs.com/xweizi/p/10551938.html
Copyright © 2011-2022 走看看