Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue从新建实例到开始diff #90

Open
andyChenAn opened this issue Sep 6, 2020 · 0 comments
Open

Vue从新建实例到开始diff #90

andyChenAn opened this issue Sep 6, 2020 · 0 comments
Labels
Vue.js Vuejs学习

Comments

@andyChenAn
Copy link
Owner

Vue从新建实例到开始diff

我们知道当我们调用new Vue的时候,首先会编译模板,生成render函数,然后调用render函数,生成vnode虚拟dom节点,然后就会调用_update函数,进行更新。

举个例子:

<div id="app">
    <div>{{name}}</div>
</div>
updateComponent = function () {
    vm._update(vm._render(), hydrating);
};
      
new Watcher(vm, updateComponent, noop, {
  before: function before () {
    if (vm._isMounted && !vm._isDestroyed) {
      callHook(vm, 'beforeUpdate');
    }
  }
}, true);

上面代码,主要做了以下几件事情:

  • 创建一个watcher对象
  • 给watcher对象绑定了回调函数(updateComponent)

每一个实例都会有自己的watcher,绑定的回调函数会在页面更新的时候调用。当我们创建watcher的时候,就会调用一次updateComponent,也就是执行:

vm._update(vm._render(), hydrating);

上面代码中,先会调用_render函数,然后调用_update函数。

_render函数是用来生成vnode节点树,_update函数是用来比较旧节点树和调用_render生成的新节点树,完成更新。

Vue.prototype._update = function (vnode, hydrating) {
  var vm = this;
  var prevVnode = vm._vnode;
  vm._vnode = vnode;
  // 省略代码...
  
  // 如果旧节点不存在,那么就进行初始化渲染,表示这是第一次渲染组件,所以不存在旧的节点
  if (!prevVnode) {
    vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */);
  } else {
    // 如果旧节点存在,那么就对比新旧节点,完成更新操作
    vm.$el = vm.__patch__(prevVnode, vnode);
  }
  // 省略代码...
};
  • 如果旧节点不存在,那么就进行初始化渲染,表示这是第一次渲染组件,所以不存在旧的节点
  • 如果旧节点存在,那么就对比新旧节点,完成更新操作

vm._vnode保存的是当前vnode节点树,当页面开始更新时,生成了新的vnode节点树,会将新的节点树赋值给vm._vnode,而将节点树保存在这里,也是为了方便获取到旧节点树。

vm.__patch__就是对比新旧节点树的地方。

@andyChenAn andyChenAn added the Vue.js Vuejs学习 label Sep 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Vue.js Vuejs学习
Projects
None yet
Development

No branches or pull requests

1 participant