vue的render函数(Vue.js 2.X支持)
- render函数的作用:render 函数 跟 template 一样都是创建 html 模板的,但是有些场景中用 template 实现起来代码冗长繁琐而且有大量重复,这时候就可以用 render 函数。
- render方法的实质就是生成template模板;
- 通过调用一个方法来生成,而这个方法是通过render方法的参数传递给它的;
- 这个方法有三个参数,分别提供标签名,标签相关属性,标签内部的html内容
- 通过这三个参数,可以生成一个完整的模板
render方法可以使用JSX语法,但需要Babel plugin插件;
render方法里的第三个参数可以使用函数来生成多个组件(特别是如果他们相同的话),只要生成结果是一个数组,且数组元素都是VNode即可;
- 因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render函数构建DOM,vue就免去了转译的过程。当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具。官网上给他起了个名字叫createElement。还有约定的简写叫h。
// @returns {VNode}
createElement(
// {String | Object | Function}
// 一个 HTML 标签字符串,组件选项对象,或者
// 解析上述任何一种的一个 async 异步函数,必要参数。
'div',
// {Object}
// 一个包含模板相关属性的数据对象
// 这样,您可以在 template 中使用这些属性。可选参数。
{
// (详情见下一节)
},
// {String | Array}
// 子节点 (VNodes),由 `createElement()` 构建而成,
// 或使用字符串来生成“文本节点”。可选参数。
[
'先写一些文字',
createElement('h1', '一则头条'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
createElement(params1,params2,params3)接受三个参数
第一个参数(必要参数):主要用于提供DOM的html内容,类型可以是字符串、对象或函数
第二个参数(类型是对象,可选):用于设置这个DOM的一些样式、属性、传的组件的参数、绑定事件之类
第三个参数(类型是数组,数组元素类型是VNode,可选):主要是指该结点下还有其他结点,用于设置分发的内容,包括新增的其他组件。注意,组件树中的所有VNode必须是唯一的
render函数的用法:
render:(h) => {
return h('div',{
//给div绑定value属性
props: {
value:''
},
//给div绑定样式
style:{
width:'30px'
},
//给div绑定点击事件
on: {
click: () => {
console.log('点击事件')
}
},
})
}
扩展:
{
// 和`v-bind:class`一样的 API
'class': {
foo: true,
bar: false
},
// 和`v-bind:style`一样的 API
style: {
color: 'red',
fontSize: '14px'
},
// 正常的 HTML 特性
attrs: {
id: 'foo'
},
// 组件 props
props: {
myProp: 'bar'
},
// DOM 属性
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
}
}
],
// Scoped slots in the form of
// { name: props => VNode | Array<VNode> }
scopedSlots: {
default: props => createElement('span', props.text)
},
// 如果组件是其他组件的子组件,需为插槽指定名称
slot: 'name-of-slot',
// 其他特殊顶层属性
key: 'myKey',
ref: 'myRef'
}
render函数中,函数可包含函数
例如:
render: function (h, params) { (h是createElement函数的简写)
return h('div', [
h('Button', {
props: {
type: 'primary',
size: 'small'
},
style: {
marginRight: '8px'
},
on: {
click: function () {
mCheck.singleShow(params.row);
}
}
}, '查看'),
h('Button', {
props: {
type: 'error',
size: 'small'
},
on: {
click: function () {
mCheck.singleDel(params.row, params.index);
}
}
}, '删除')
]);
}
- 在iview中使用:
<Table width="100%" stripe :columns="tableColumns" :data="tableData"></Table>
{
title: "操作",
align: "center",
width: 200,
render: (h, params) => {
return h("div", [
h(
"Button", {
props: {
type: "text",
size: "small"
},
style: {
backgroundColor: "#2db7f5",
color: "#fff",
marginRight: "5px"
},
on: {
click: () => {
parentObj.$router.push({
name: 'equipmentdetail',
params:{
from: parentObj.$route.name,
item: params.row
}
})
}
}
},
"详情"
),
h(
"Button", {
props: {
type: "text",
size: "small"
},
style: {
backgroundColor: " #19be6b",
color: "#fff",
marginRight: "5px"
},
on: {
click: () => {
parentObj.$router.push({
name: 'editequipment',
params:{
item: params.row
}
})
}
}
},
"修改"
)
}
在element中使用
<el-table-column
:render-header="item.renderHeaderFuc"
v-for="(item,index) in tableColumns"
:key="index"
:prop="item.prop"
:align="item.align"
:minWidth="item.minWidth"
:label="item.label"
>
</el-table-column>
renderHeaderFuc: (h,params)=> {
console.log(h,params)
return h('div',[
h('button', {
props:{
type: "primary",
size: "small"
},
style:{
},
on:{
click: ()=>{
this.$router.push({
name:'tradecustomeredit',
params: {
tradecustomer: params,
}
})
}
}
},'编辑')
])
}
在element中使用时控制台会报一个警告,
[Element Warn][TableColumn]Comparing to render-header, scoped-slot header is easier to use. We recommend users to use scoped-slot header,与render-header相比,作用域槽头更易于使用。我们建议用户使用范围槽头,所以建议使用插槽来写