VUE渲染函数render function

241 阅读2分钟

渲染函数render function

本文记录自尤小右的视频教学。

模板template

  1. ast树抽象语法树
  2. compiled into Render Function 编译成渲染函数
  3. return Virtual DOM 返回虚拟dom元素
  4. generates Actual DOM 生成真实dom元素

vue的templates实际上是由渲染函数渲染出来的,当我们渲染一个vue应用,我们会将template放到渲染函数进行编译,这会发生在你使用完整的编译模式,也就是你直接使用dom模板,就像你直接在dom中编写模板一样。或者直接给vue实例传递一个模板字符串,但是如果你使用vue-cli来构建项目,用到webpack和vue-loader,它实际上是在构建时预编译模板,所以浏览器访问的代码是不包含原始模板的,相反它提供了编译的渲染函数代码,这是纯js。这样做会节省很多编译时间,而且我们可以在没有编译器的情况下运行。在vue中我们提供两种构建方式,一种是完整的构建,它包含一个编译器gzip后大概30kb,但是不包含编译器只包含运行时大小就只有20kb。

render函数实际上是返回虚拟dom,然后vue基于虚拟dom生成真实dom。我们产生虚拟dom的过程本质上是调用render函数,因为render函数和所有的data属性有依赖关系,同时这些data属性是具有响应性的,所有的这些data属性会帮助这个组件的渲染函数收集依赖,如果这些依赖属性中发生了任何变化,将会再次调用渲染函数,它会返回新的虚拟dom,此时新旧的虚拟dom将被比较和区分。

虚拟dom的优点(误区:让框架运行的更快)

  1. 以声明的方式构成你想要的dom结构
  2. 把渲染逻辑从真实的dom中分离出来,先计算差异再应用dom中

每个组件都有自己的自动循环渲染,组件只负责自己的依赖

插槽

你可以通过 this.$slots 访问静态插槽的内容,每个插槽都是一个 VNode 数组:
render: function (createElement) {
  // `<div><slot></slot></div>`
  return createElement('div', this.$slots.default)
  //等同于
  return createElement('div', this.$scopedSlots.default())
  
  //作用域插槽
  return createElement('div', this.$scopedSlots.default({a: 1}))
}

this.$scopedSlots.default() === this.$slots.default   //true

抽象组件

export default {
  name: 'debounce',
 
  abstract: true, //标记为抽象组件
 
  render() {
    let vnode = this.$slots.default[0]; // 子组件的vnode
    if (vnode) {
      let event = get(vnode, `data.on.click`); // 子组件绑定的click事件
      if (typeof event === 'function') {
        set(vnode, `data.on.click`, debounce(event, 1000));
      }
    }
    return vnode;
  }
};