最近在项目开发过程中,经常用到 UI 组件库中的 render 函数来渲染内容。今天来总结一下 render 的用法。
Render 函数
在 Vue 2 中,render 函数是一个用于创建 Vue 组件虚拟 DOM 的函数。它允许你以编程方式定义组件的结构,而不是使用模板语法。
render 函数接受一个 createElement 函数作为参数,并返回一个虚拟 DOM 节点。createElement 函数用于创建 Vue 的虚拟节点(VNode)。
基本结构
js
render(createElement) {
return createElement(
'div', // 标签名
{ class: 'my-class' }, // 属性对象
[
createElement('h1', 'Hello World'), // 子节点
createElement('p', 'This is a paragraph.')
]
);
}
用途
- 复杂逻辑: 当模板语法无法满足复杂逻辑需求时,可以使用 render 函数编写更复杂的组件结构。
- 动态内容: render 函数可以用来创建动态的虚拟 DOM,允许更细粒度地控制组件的渲染。
- 性能优化: 在某些性能要求高的场景中,render 函数可能提供比模板更高效的渲染方式。
render 函数最常见的地方就是表格的 columns。
Render 写法
通过给
columns
数据的项,设置一个函数render
,可以自定义渲染当前列,包括渲染自定义组件,它基于 Vue 的 Render 函数。
render
函数传入两个参数,第一个是 h,第二个是对象,包含row
、column
和index
,分别指当前单元格数据,当前列数据,当前是第几行。
将h
作为createElement
的别名是 Vue 生态系统中的一个通用惯例,实际上也是 JSX 所要求的。从 Vue 的 Babel 插件的 3.4.0 版本开始,我们会在以 ES2015 语法声明的含有 JSX 的任何方法和 getter 中 (不是函数或箭头函数中) 自动注入const h = this.$createElement
,这样你就可以去掉(h)
参数了。对于更早版本的插件,如果h
在当前作用域中不可用,应用会抛错。-- v2.cn.vuejs.org/v2/guide/re...
基本语法
html
<template>
<Table :columns="columns" :data="data"></Table>
</template>
<script>
export default {
data() {
return {
data: [
{ name: 'John', age: 30 },
{ name: 'Jane', age: 24 }
],
columns: [
{
title: 'Name', // 列的标题为 'Name'
key: 'name', // 数据中对应的键为 'name'
render: (h, params) => {
// render 函数,用于自定义渲染列的内容
return h('div', [
// 创建一个 <div> 元素
h('Icon', {
// 在 <div> 中创建一个 <Icon> 组件
props: {
type: 'person' // 设置 <Icon> 组件的属性 'type' 为 'person'
}
}),
h('strong', params.row.name)
// 在 <div> 中创建一个 <strong> 元素,并显示当前行的数据中的 'name' 字段
]);
}
}
]
};
}
};
</script>
render 函数有两个参数, 最主要的是第一个参数 h 函数, 第二个参数是组件库自己封装的对外暴露的数据。
h 函数
在 Vue.js 中,h 函数通常是 createElement 的别名 ,用于创建虚拟 DOM 元素。在使用 Vue 的 render 函数时,h 函数是非常重要的,它可以创建任何你想要的 DOM 结构或组件。让我们详细解析 h 函数的用法和参数。
h 函数的三种用法
h 函数是 Vue 的 createElement 函数的缩写形式。它有三种主要的用法:
创建普通元素
创建了一个 div 元素,具有 class="my-class",并包含文本 "Hello World"。
js
h('div', { class: 'my-class' }, 'Hello World')
创建组件
创建了一个 MyComponent 组件,并传递了 someProp 属性。
js
h(MyComponent, { props: { someProp: 'value' } })
嵌套子节点
创建了一个 ul 元素,包含两个 li 子节点。
js
h('ul', [
h('li', 'Item 1'),
h('li', 'Item 2')
])
h 函数的参数
h 函数通常接收三个参数:
- 标签名或组件(tag): 可以是一个字符串(表示 HTML 标签) 或者是一个组件对象。
- 数据对象(data):一个包含属性、事件、样式等信息的对象(可选)。
- 子节点(children):一个子节点、一个子节点数组或者是字符串(可选)。
只有两个参数的情况
当使用 Vue.js 的 h 函数(createElement)时,如果只提供两个参数,这两个参数通常是标签名或组件以及子节点。数据对象(第二个参数)是可选的,所以如果你只提供两个参数,Vue 会将第二个参数解释为子节点。
js
h('div', 'Hello World')
到这里基本可以熟练的掌握用 h 函数来创建基本的虚拟 DOM 元素的了。
深入了解数据对象参数
下面主要来看一下数据对象(data) : 包含属性、事件、样式等信息的对象 的参数。下面是完整的数据对象声明参考。
常用项需要注意的几个点是:
- class 和 style 直接定义, HTML属性定义在 attrs 对象内
- 组件的 prop 定义在 props 中, DOM 属性定义在 domProps 中
- 组件事件在
on
中定义, 原生事件 在 nativeOn 中定义 - 作用域插槽在 scopedSlots 中定义
js
{
// 与 `v-bind:class` 的 API 相同,
// 接受一个字符串、对象或字符串和对象组成的数组
'class': {
foo: true,
bar: false
},
// 与 `v-bind:style` 的 API 相同,
// 接受一个字符串、对象,或对象组成的数组
style: {
color: 'red',
fontSize: '14px'
},
// 普通的 HTML attribute
attrs: {
id: 'foo'
},
// 组件 prop
props: {
myProp: 'bar'
},
// DOM property
domProps: {
innerHTML: 'baz'
},
// 事件监听器在 `on` 内,
// 但不再支持如 `v-on:keyup.enter` 这样的修饰器。
// 需要在处理函数中手动检查 keyCode。
on: {
click: this.clickHandler
},
// 仅用于组件,用于监听原生事件,而不是组件内部使用
// `vm.$emit` 触发的事件。
nativeOn: {
click: this.nativeClickHandler
},
// 自定义指令。注意,你无法对 `binding` 中的 `oldValue`
// 赋值,因为 Vue 已经自动为你进行了同步。
directives: [
{
name: 'my-custom-directive',
value: '2',
expression: '1 + 1',
arg: 'foo',
modifiers: {
bar: true
}
}
],
// 作用域插槽的格式为
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props => createElement('span', props.text)
},
// 如果组件是其它组件的子组件,需为插槽指定名称
slot: 'name-of-slot',
// 其它特殊顶层 property
key: 'myKey',
ref: 'myRef',
// 如果你在渲染函数中给多个元素都应用了相同的 ref 名,
// 那么 `$refs.myRef` 会变成一个数组。
refInFor: true
}
场景示例
渲染组件
js
render: (h, {column,row,index}) => {
return h('div', [
h(
'Button', {
props: {
type: 'primary'
},
on: {
click: () => {
this.handleClick(row.id)
}
}
},
'编辑'
)])
渲染作用域插槽
js
render: (h, params) => {
return h("i-switch", {
props: {
size: "large",
trueValue: 1,
falseValue: 0,
value: params.row.status,
disabled: !params.row.disbaled
},
scopedSlots: {
open: () => h("span", "是"),
close: () => h("span", "否")
},
on: {
"on-change": value => {
this.handleChange(value);
}
}
});
}
},
结语
在 Vue 2 中,render 函数是一个极具灵活性的工具,能够帮助我们创建复杂的组件结构和优化性能。本文详细探讨了 render 函数的基本概念、常见用法及其在实际开发中的应用场景。通过学习 render 函数,我们不仅可以应对复杂的业务需求,还能在构建动态内容和提升应用性能方面获得更多的选择和控制。
掌握 render 函数及其 h 函数的用法,将有助于你在 Vue 项目中实现更高效的组件开发。希望本文的总结对你有所帮助,也鼓励你在实际项目中灵活运用这些知识,探索 Vue 的更多高级功能。
参考资料
-
vue2官方网站-渲染函数:v2.cn.vuejs.org/v2/guide/re...
-
VNode: github.com/vuejs/vue/b...
- Vnode(虚拟节点)是 Vue.js 中用于表示 DOM 结构的轻量级对象,它抽象了真实的 DOM 元素,从而使 Vue.js 能够高效地进行 DOM 操作和更新。