工作生活

vue算是很通俗的源码分析(面试装逼大法)

2019-07-02  本文已影响0人  凉宫春日的简书

1.请你说下数据绑定(数据绑定原理):

image

初始化data(个人简化了的initData)

function initData (vm: Component) {
  /*得到data数据*/
  let data = vm.$options.data
  
  /*遍历data,和props对象*/
  const keys = Object.keys(data)
  const props = vm.$options.props
  let i = keys.length

  //遍历data中的数据,且props和data没有key没有冲突
  while (i--) {
      if (!(props && hasOwn(props, keys[i]))) { 
        proxy(vm, `_data`, keys[i])
      }    
      /*这里是我们前面讲过的代理,将data上面的属性代理到了vm实例上*/
    }
  }
  /*从这里开始我们要observe了,开始对数据进行绑定*/
  observe(data, true /* asRootData */)
}

initData函数主要做了两件事:

proxy

/*添加代理*/
export function proxy (target: Object, sourceKey: string, key: string) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  }
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val
  }
  Object.defineProperty(target, key, sharedPropertyDefinition)
}

Observe

Watcher

Dep

defineReactive


2.小伙子,说下虚拟dom:

3.那diff算法你知道怎么运作的吗?

4.使用v-for进行列表渲染的时候,加:key的效果是什么,为什么会这样?

延伸: 更新虚拟dom的规则是这样:

1.如果新旧VNode都是静态的,同时它们的key相同(代表同一节点),并且新的VNode是clone或者是标记了once(标记v-once属性,只渲染一次),那么只需要替换elm以及componentInstance即可。

2.新老节点均有children子节点,则对子节点进行diff操作,调用updateChildren,这个updateChildren也是diff的核心。

3.如果老节点没有子节点而新节点存在子节点,先清空老节点DOM的文本内容,然后为当前DOM节点加入子节点。

4.当新节点没有子节点而老节点有子节点的时候,则移除该DOM节点的所有子节点。

5.当新老节点都无子节点的时候,只是文本的替换。

上一篇 下一篇

猜你喜欢

热点阅读