# 渲染函数 API
非兼容

# 概览

此更改不会影响 <template> 用户。

以下是更改的简要总结:

  • h 现在是全局导入,而不是作为参数传递给渲染函数
  • 更改渲染函数参数,使其在有状态组件和函数组件的表现更加一致
  • VNode 现在有一个扁平的 prop 结构

请继续阅读来获取更多信息!

# 渲染函数参数

# 2.x 语法

在 2.x 中,render 函数会自动接收 h 函数 (它是 createElement 的惯用别名) 作为参数:

// Vue 2 渲染函数示例
export default {
  render(h) {
    return h('div')
  }
}
1
2
3
4
5
6

# 3.x 语法

在 3.x 中,h 函数现在是全局导入的,而不是作为参数自动传递。

// Vue 3 渲染函数示例
import { h } from 'vue'

export default {
  render() {
    return h('div')
  }
}
1
2
3
4
5
6
7
8

# 渲染函数签名更改

# 2.x 语法

在 2.x 中,render 函数自动接收参数,如 h 函数。

// Vue 2 渲染函数示例
export default {
  render(h) {
    return h('div')
  }
}
1
2
3
4
5
6

# 3.x 语法

在 3.x 中,由于 render 函数不再接收任何参数,它将主要在 setup() 函数内部使用。这还有一个好处:可以访问在作用域中声明的响应式状态和函数,以及传递给 setup() 的参数。

import { h, reactive } from 'vue'

export default {
  setup(props, { slots, attrs, emit }) {
    const state = reactive({
      count: 0
    })

    function increment() {
      state.count++
    }

    // 返回渲染函数
    return () =>
      h(
        'div',
        {
          onClick: increment
        },
        state.count
      )
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

有关 setup() 如何工作的详细信息,请参考组合式 API 指南

# VNode Prop 格式化

# 2.x 语法

在 2.x 中,domProps 包含 VNode prop 中的嵌套列表:

// 2.x
{
  staticClass: 'button',
  class: { 'is-outlined': isOutlined },
  staticStyle: { color: '#34495E' },
  style: { backgroundColor: buttonColor },
  attrs: { id: 'submit' },
  domProps: { innerHTML: '' },
  on: { click: submitForm },
  key: 'submit-button'
}
1
2
3
4
5
6
7
8
9
10
11

# 3.x 语法

在 3.x 中,整个 VNode prop 的结构都是扁平的。使用上面的例子,来看看它现在的样子。

// 3.x 语法
{
  class: ['button', { 'is-outlined': isOutlined }],
  style: [{ color: '#34495E' }, { backgroundColor: buttonColor }],
  id: 'submit',
  innerHTML: '',
  onClick: submitForm,
  key: 'submit-button'
}
1
2
3
4
5
6
7
8
9

# 注册组件

# 2.x 语法

在 2.x 中,注册一个组件后,把组件名作为字符串传给渲染函数的第一个参数,渲染函数可以正常的工作:

// 2.x
Vue.component('button-counter', {
  data() {
    return {
      count: 0
    }
  }
  template: `
    <button @click="count++">
      Clicked {{ count }} times.
    </button>
  `
})

export default {
  render(h) {
    return h('button-counter')
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 3.x 语法

在 3.x 中,由于 VNode 是上下文无关的,不能再用字符串 ID 隐式查找已注册组件。相反地,需要使用一个导入的 resolveComponent 方法:

// 3.x
import { h, resolveComponent } from 'vue'

export default {
  setup() {
    const ButtonCounter = resolveComponent('button-counter')
    return () => h(ButtonCounter)
  }
}

1
2
3
4
5
6
7
8
9
10

更多信息请参考渲染函数 API 更改 RFC(opens new window)

# 迁移策略

迁移构建标记:RENDER_FUNCTION

# 工具库作者

全局导入 h 意味着任何包含 Vue 组件的库都将在某处包含 import { h } from 'vue'。这会带来一些开销,因为它需要库作者在其构建设置中正确配置 Vue 的外部化:

  • Vue 不应绑定到库中
  • 对于模块构建,导入应该保持独立,由最终用户的打包器处理
  • 对于 UMD / browser 构建,应该首先尝试全局 Vue.h,不存在时再使用 require 调用

# 下一步

详细文档请参考 Render 函数指南