最近,由于业务需求使用iview作为前端UI框架,在处理table的时候总是,有些不满意的地方,最后发现在iview可以使用vue的render函数。特此记录。
Render函数:render函数接收一个 createElement 方法作为第一个参数用来创建VNode(虚拟DMO)
render: function (createElement) {
//do something
return creatElement(参数1, 参数2, 参数3)
}
createElement(参数1, 参数2, 参数3) 中有三个参数
- 参数1:必须,规定将要渲染的HTML标签是什么。类型可以是字符串、对象或函数。比如”div”就是创建一个
<div>
标签 。 - 参数2:可选,类型是对象。主要用于设置这个dom的一些样式、属性、传的组件的参数、绑定事件之类。
- 参数3:可选,"文本节点",类型是数组或字符串
参数2中可用参数之类的:
{
'class': {
// 和`v-bind:class`一样的API
},
style: {
// 和`v-bind:style`一样的API
},
attrs: {
// 正常的 html 特性
},
props: {
// 组件 props
},
domProps: {
// DOM 属性
},
on: {
// 事件监听器基于on
// 不再支持如 `v-on:keyup.enter` 修饰器,需手动匹配 keyCode
},
nativeOn: {
// 仅对于组件,用于监听原生组件,而不是组件内部使用`vm.$emit`触发的事件
},
directives: [
{
// 自定义指令,注意事项:不能对绑定的旧值设值
// vue 会为您持续追踪
}
],
scopedSlots: {
},
slot: '', // 如果组件是其他组件的子组件,需为 slot 指定名称
// 其他特殊顶层属性
key: '',
ref: ''
}
案例:
render: function (createElement) {
var self = this
return createElement('button', {
class: 'isTest',
on: {
click: () => { alert('1') }
}
},'点击我')
}
将会渲染成这样:
<button class='isTest'>点击我<button>
//并且有点击事件
将 h 作为 createElement 的别名是 Vue 生态系统中的一个通用惯例。所以有了其他写法。
ES5:
new Vue({
el: '#demo',
render: function (h) {
return (
h(APP)
)
}
})
ES6:
new Vue({
el: '#demo',
render: h => h(APP)
})
关于一个render渲染内部多个子元素:
在第二个参数中写入一个数组,数组中可以用h再次创建 Vnode
render: h => {
return h('div',[
h('button',{
style:{color:red;},
attrs:{....}
},'提交'),
h('input',{....}),
h('p',{.....},'我是P标签内的内容'),
])
}
一个实践案例:
{
title: '操作',
align: 'center',
width: 125,
render: (h, params) => {
let isChange;
let isUsed = true;
let status = params.row.billStatus;
if (status == '0') {
isChange = '开票'; //未开,开具操作
isUsed = false
} else if (status == '1') {
isChange = '已开';
isUsed = true
}
return h('div', [
h('Button', {
props: {
size: 'small',
type: 'primary',
disabled: isUsed
},
on: {
click: () => {
let data = params.row;
if (!isUsed) {
axios.get('/bill/open?id=' + data.id).then(
response => {
let res = JSON.parse(response.request.response);
// console.log(res.data)
if (res.code == '200') {
this.$Message.success('开票成功!');
this.checked()
} else {
this.$Message.error('开票失败!')
}
}
);
}
}
}
}, isChange),
h('Button', {
props: {
size: 'small',
type: 'info'
},
style: {
marginLeft: '5px'
},
on: {
click: () => {
let data = params.row;
axios.get('bill/billDetail?id=' + data.id).then(
response => {
let res = JSON.parse(response.request.response);
// console.log(res.data)
if (res.code == '200') {
this.siteData = res.data.memAddressVO;
this.orderData = res.data.orderListVoList;
this.billData = res.data.memBillVo;
this.amount = res.data.amount;
this.isTurn()
}
}
);
}
}
}, '详情'),
]);
}
}