深入理解Render函数和函数式组件用法

1,542 阅读1分钟

render函数特点

  • render函数和模板一样,模板可以做的事情它都可以做
  • render函数是最接近编译器的函数
  • render函数返回vnode
  • 模板和jsx会先编译成render函数然后在返回vnode
  • 组件树中的所有 VNode 必须是唯一的,如果真的需要重复很多次的元素/组件,你可以使用工厂函数来实现
  • 渲染函数中没有与v-model的直接对应——你必须自己实现相应的逻辑
  • Vue 选项中的render函数若存在,则 Vue 构造函数不会从template选项或通过el选项指定的挂载元素中提取出的 HTML 模板编译渲染函数。
  • render函数一般结合函数式组件来用,函数式组件只是函数,所以渲染开销也低很多
  • 只要在原生的 JavaScript 中可以轻松完成的操作,Vue 的渲染函数就不会提供专有的替代方法

render函数注意点

  • createElement第一个参说若是组件,则第三个参数可省略,即使写上去了也无效
  • createElement的第二个参数可省略不写
  • render函数在on事件中可监听组件$emit发出的事件

函数式组件特点

  • 无状态 (没有响应式数据也就是无data,即使在组件中声明了data也是不可用的)
  • 没有实例 (没有this上下文,普通文件this指向window,在单文件中this指向null)

为什么要用函数式组件

  1. 函数式组件只是函数,无状态 (没有响应式数据),不需要递归监听data中的数据,也没有实例 (没有this上下文),所以渲染开销相比于模板低很多,所以用于渲染静态数据非常高效

  2. 作为包装组件时它非常有用,如果有多个组件,可以有选择的渲染某个组件

  3. 方便开发者定义很逻辑清晰的组件

函数式组件在单文件组件中的应用

如果在单文件组件中声明了函数式组件,不可再用render函数【因为vue-loader是把template转换成render函数 templete和render函数不能共存】 vue单文件里并没有render方法,因此不会执行

错误示例

codesandbox.io/s/vuejscesh…

解决办法有3种

codesandbox.io/s/vue-templ…

https://codesandbox.io/s/vue-template-ok0ei

https://codesandbox.io/s/vuejsceshidanyemianzujianzuohanshushizujian-hfvst

render函数渲染多个值

  render: function(createElement) {
      return createElement('div', [
        createElement('span', '123'),
        createElement('span', '456')
      ])
   }

iview2.0表格中使用render函数

原理

其实就是我们引入的表格组件 表格组件是一个js文件 这个js文件是函数式组件和render函数结合来使用的【详细需要看源码】 iview3.0之后废弃了表格中使用render函数

排坑

iview2.0表格中使用render函数 在scope下css不起作用

后记

想要查看一个组件的模板被编译后的渲染函数很简单,只需要在访问 this.$options.render 即可

注意 空格也会被createElement()渲染

<div>
  <base-component>
    <h2 slot="slot1">BaseComponent slot</h2>
    <p>default slot</p>
  </base-component>
</div>

转换后

var render = function() {
  var _vm = this
  var _h = _vm.$createElement
  var _c = _vm._self._c || _h
  return _c(
    "div",
    [
      _c("base-component", [
        _c("h2", { attrs: { slot: "slot1" }, slot: "slot1" }, [
          _vm._v("BaseComponent slot")
        ]),
        _vm._v(" "),
        _c("p", [_vm._v("default slot")])
      ])
    ],
    1
  )
}