# Vue主线剧情之vm._render

# 前言

前面说过的vm.$mount,在 new Wather 中,会调用 updateComponent 方法。在这个方法中生成虚拟Node节点(vNode),最后调用 vm._update 来更新Dom,那么其中最核心的就是 vm._rendervm._update

这里我们就来详细了解一下 vm._render

忘了 updateComponent 方法的点击这里: updateComponent

# 源码

emm... 不看源码就说流程的都是耍流氓。

_render 定义在 src/core/instance/render.js

# 大概看了看

嗯~,果然不出所料,vm._render 就是生成vNode了,所以我们只需要找到其中最关键的地方就行了。

在哪里呢? 那就是 vnode = render.call(vm._renderProxy, vm.$createElement)

不过后面好像还有一个 renderError.call, 看它的参数估摸着和render做的事情差不多。

# 还记得Vue的options吗?

这里是贼重要的一句

所以,render是从vm.$options中拿的咯。

让我们回到Vue.js的Api

你是否像这样调用过呢?

// render
new Vue({
  render: function (createElement) {
   return createElement('div', {
        attrs: {
            id: 'app'
        },
    }, this.message)
  },
  renderError: function(createElement, err) {
    return createElement('pre', { style: { color: 'red' }}, err.stack)
  }
}).$mount('#app')

---

// renderError
new Vue({
  render (h) {
    throw new Error('oops')
  },
  renderError (h, err) {
    return h('pre', { style: { color: 'red' }}, err.stack)
  }
}).$mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

所以结合一下就可以看出 render 方法的参数 createElement 实际上就是 vm.$createElement, 然而 vm.$createElement 在初始化中就已经执行过了。

具体看这里: initRender

我们发现 initRender 方法中,除了 vm.$createElement 方法,还有一个 vm._c 方法,它是被模板编译成的 render 函数使用,但 vm.$createElement 是我们用原生写的 render 方法使用的, 这俩个方法支持的参数相同,并且内部都调用了 createElement 方法。

官网说的非常清楚:

The render function has priority over the render function compiled from template option or in-DOM HTML template of the mounting element which is specified by the el option.

也就是如果你在options配置项中传入了自己写的render函数,会优先于template和outhorHtml(in-DOM HTML template)的编译渲染功能。

# 总结

经过一番查找,终于得到了结论, render 函数最终是执行 createElement 方法,返回 vnode 节点,这是一个虚拟 node

阿西吧 终于提到了虚拟dom的概念了。。。 感觉有盼头了

Vue的另一个核心就是用到了Virtual DOM,实际上是借鉴了开源库 snabbdom 的实现,然后加入了一些自己的东西。

接下来我们将继续追寻 createElement 方法。


两个扩展问题:

  • 操作 Virtual DOM 快还是真实 DOM 快?
  • Vue的Dom diff你了解多少? (好像在这里问不太合适,算了,先问了再说)

# 致谢

感谢大家阅读我的文章,如果对我感兴趣可以点击页面右上角,帮我点个star。

作者:前端小然子

链接: https://xiaoranzife.com/guide/vue/vm._render.html

来源:前端小然子的博客

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

上次更新: 2019-11-21 2:45:47 ├F10: PM┤