iview使用render函数渲染嵌套表格
最近做项目遇到iview表格渲染,通过render函数来实现循环嵌套渲染表格及单元格内容,返回文字提示包含icon按钮的图标,当鼠标移到“复制”图标上时显示tooltip内容,单击实现复制,接下来就把遇到的问题总结一下。
1.初始化表格
<!-- 表格 S -->
<Table
v-if="hostsList && !error"
border
ref="selection"
:columns="columns"
:data="hostsList"
@on-selection-change="tableSelection"
@on-select="tableSelect"
></Table>
<!-- 表格 E -->
初始化data中返回的数据
columns: [ //表格头部 信息 id hostname tags loc idc status
{
type: 'selection',
width: 60,
align: 'center',
},
{
title: '机器名称',
key: 'hostname',
width: 200,
render: (h, params) => {
let data =params.row;
let url = '';
if(data.idc === 'uclcn' || data.idc === 'alicn' || data.idc === 'tencn') {
url = `http://${data.hostname}:1988`
} else {
url = `http://${data.ip}:1988`
}
return h('a',
{
domProps:{
href: url,
target:'_blank'
}
},
data.hostname
)
}
},
{
title: '机器IP',
key: 'ip',
width:150,
align: 'center',
},
{
title: '机器类型',
key: 'type',
width:150,
align: 'center',
render: (h, params) => {
console.log( 99999, h ,params)
let data = params.row;
let type = ''
if (data.type == 'commodo') {
type = '虚拟机'
} else {
type = '容器'
}
return h('div',
{},
type
)
}
},
{
title: '节点',
key: 'tags',
minWidth:450,
render: (h, params) => {
let data =params.row.tags;
let _this = this
return h('div', data.map( (item)=>{
return h('div', {
style: {
// padding: '5px 0',
// lineHeight: '24px',
}
},[
h('a',{
style:{
display: 'inline-block',
padding: '5px 0',
lineHeight: '24px',
fontSize: '12px',
},
on:{
click: () => {
let href = window.location.href
let host = href.split('?')[0]
window.location.href = host + '?tagstring=' + item
window.location.reload()
}
}
}, item ),
h('Poptip', {
props: {
trigger:"hover",
placement: 'top',
// 注意一定要添加该属性,否则表格会遮盖住气泡浮框
transfer: true,
content: '复制',
// width: '20px',
}
},
[
h('Icon', {
class: 'ivu-icon ivu-icon-ios-copy-outline copyBtn1',
style: {
marginleft: '15px',
cursor: 'pointer'
},
props: {
type:"ios-copy-outline"
},
on: {
click: () => {
console.log(99999)
//头部copy文本方法
let Clipboard = this.base.Clipboard; //调用公共复制文本方法
var clipboard = new Clipboard('.copyBtn1' , {
text: function() {
clipboard.destroy();
return item;
}
});
clipboard.on('success', function(e) {
e.clearSelection();
_this.$Message.success('复制成功~');
});
clipboard.on('error', (e)=>{
clipboard.destroy();
_this.$Message.error('复制失败,请手动复制~')
});
}
}
})
]
)]
)
}),
)}
},
{
title: '操作',
key: 'action',
width: 150,
align: 'center',
render: (h, params) => {
return h('div', [
h('Button', {
props: {
type: 'success',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
if(this.popup){ //第一个弹框是打开状态的时候什么也不做
return;
}
//this.clickBindIP( params.row , params.index ); //传递给点击绑定事件
let data = params.row;
this.rename.isLayer = true;
this.rename.lodVal = data.hostname;
this.rename.id = data.id;
this.rename.head = data.loc+'-' //新名字的头
this.rename.tail = '.'+data.idc //新名字的尾部
}
}
}, '改名'),
h('Button', {
props: {
type: 'error',
size: 'small'
},
on: {
click: () => {
//this.removeBindIP(params.row , params.index)
this.$Message.info('您点击了重启按钮')
}
}
}, '重启')
]);
}
}
],
2.render函数返回节点格式
iview表格的render函数作用是自定义渲染当前列,权限高于key,所以使用了render函数,那么表格的key值就无效了。render函数传入两个参数,第一个是 h,第二个是对象,包含 row、column 和 index,分别指当前单元格数据,当前列数据,当前是第几行。
具体用法:
render:(h,params) => {
return h(" 定义的元素 ",{ 元素的性质 },"元素的内容"/[元素的内容])
}
1.返回单文本
如果是可以直接用的数据字段,直接把字段赋值给key值就可以了
{
title: '机器IP',
key: 'ip',
width:150,
align: 'center',
},
2.返回自定义文本
使用return h函数返回
{
title: '机器名称',
key: 'hostname',
width: 200,
render: (h, params) => {
let data =params.row;
let url = '';
if(data.idc === 'uclcn' || data.idc === 'alicn' || data.idc === 'tencn') {
url = `http://${data.hostname}:1988`
} else {
url = `http://${data.ip}:1988`
}
// 如果不做以上操作可直接使用return h函数返回
return h('a', // 元素名称
{
domProps:{
href: url,
target:'_blank'
}// 为元素赋属性
style: {
fontSize: '14px'
}// 为元素写样式,驼峰书写格式,值加“”
}, // 元素性质
on: {
click: () => {}
}, // 元素事件
data.hostname // 元素内容
)
}
},
3.返回html元素/多元素/嵌套元素
在单元格还要循环元素的话就在render h里使用map函数返回,然后内层再使用一个render h 函数返回循环内容。
返回html元素/多元素/嵌套元素时要记得在节点外加“[ ]”,不加的话渲染不出来,但也不会报错,“[ ]”中使用h函数逐层返回,不用再加’return’,格式同return h 函数
格式:
h(" 定义的元素 ",{ 元素的性质 },"元素的内容"/[元素的内容])
render: (h, params) => {
return h('a', [
h('a',[
h('Icon', {
})
])
])
})
例:
{
title: '节点',
key: 'tags',
minWidth:450,
render: (h, params) => {
let data =params.row.tags;
let _this = this
return h('div', data.map( (item)=>{
return h('div', { // 单元格中再渲染循环肉
style: {
// padding: '5px 0',
// lineHeight: '24px',
}
},[ //此处"[]"是必须的
h('a',{
style:{
display: 'inline-block',
padding: '5px 0',
lineHeight: '24px',
fontSize: '12px',
},
on:{
click: () => {
let href = window.location.href
let host = href.split('?')[0]
window.location.href = host + '?tagstring=' + item
window.location.reload()
}
}
}, item ),
h('Poptip', {
props: {
trigger:"hover",
placement: 'top',
// 注意一定要添加该属性,否则表格会遮盖住气泡浮框
transfer: true,
content: '复制',
// width: '20px',
}
},
[ //此处"[]"是必须的
h('Icon', {
class: 'ivu-icon ivu-icon-ios-copy-outline copyBtn1',
style: {
marginleft: '15px',
cursor: 'pointer'
},
props: {
type:"ios-copy-outline"
},
on: {
click: () => {
console.log(99999)
//头部copy文本方法
let Clipboard = this.base.Clipboard; //调用公共复制文本方法
var clipboard = new Clipboard('.copyBtn1' , {
text: function() {
clipboard.destroy();
return item;
}
});
// 复制成功 clipboard.on('success', function(e) {
e.clearSelection();
_this.$Message.success('复制成功~');
});
// 复制失败 clipboard.on('error', (e)=>{
clipboard.destroy();
_this.$Message.error('复制失败,请手动复制~')
});
}
}
})
]
)]
)
}),
)}
},
3.render中使用this
render中使用this会报undefined,所以要在起始处给this赋值
render: (h, params) => {
let data =params.row.tags;
let _this = this
....
})