需求:要实现表格自定义样式(即表格中自己随意定义html模板),以及要能随着数据库状态手动刷新相关状态,且包含分页功能,如下图:
实现:
html部分:
<Table highlight-row border @on-selection-change="selectChange" :context="self" :columns="columns" :data="data">
<template slot-scope="{ row }" slot="enabled">
<i-switch size="large" v-model="row.enabled" @on-change="switchChange(row)">
<span slot="open">开启</span>
<span slot="close">关闭</span>
</i-switch>
</template>
</Table>
<div style="margin: 10px;overflow: hidden">
<div style="float: right;">
<Page :total="total" :current="pageQuery.pageNum" :page-size-opts=[10,30,50,100,500]
@on-change="changePage" @on-page-size-change="pageSizeChange" show-total show-elevator show-sizer>
</Page>
</div>
</div>
数据定义(vue的data部分):
两种方式实现switch:(其他在表格中要实现的组件同理)
1.用render函数,如下注释部分,在html中不需要写组件代码了,但是不好刷新数据状态
2.用template的slot插槽方式,在定义数据中要定义插槽字段slot,推荐用这种方式
columns: [
{
type: 'selection',
width: 60,
align: 'center'
},
{
type: 'index',
width: 60,
align: 'center'
},
{
title: '姓名',
align: 'center',
key: 'nickname'
},
{
title: '手机号',
align: 'center',
key: 'phoneNum'
},
{
title: '用户名',
align: 'center',
key: 'userName'
},
{
title: '所属角色',
align: 'center',
key: 'roleData',
render: (h, params) => {
return h('div', [
h('span', {
// 添加class名称
class: 'classNames'
style: {
color: '#5cadff'
}
// 如果该字段为null则显示无
}, params.row.roleData !== null ? params.row.roleData.roleName : '无')
])
}
},
{
title: '邮箱',
align: 'center',
key: 'email'
},
{
title: '性别',
align: 'center',
key: 'sex'
},
{
title: '出生年月',
align: 'center',
key: 'birthday'
},
{
title: '是否冻结',
align: 'center',
slot: 'enabled'
// 状态不使用render函数,因为不刷新
// key: 'enabled'
// render: (h, params) => {
// return h('div', [
// h('i-switch', {
// props: {
// type: 'primary',
// size: 'large',
// value: params.row.enabled,
// // value: 1,设置显示开关显示的值
// 'true-value': 1,
// 'false-value': 0
// },
// scopedSlots: {
// open: function() { return h("span", "启用") },
// close: function() { return h("span", "冻结") }
// },
// on: {
// 'on-change': (value) => { // 触发事件是on-change,用双引号括起来,
// this.switchChange(params, value) // params.index是拿到table的行序列,可以取到对应的表格值
// }
// }
// })
// ])
// }
},
{
title: '操作',
key: 'action',
fixed: 'right',
width: 220,
align: 'center',
render: (h, params) => {
return h('div', [
h('Button', {
props: {
type: 'primary',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
this.editorButton(params.row)
}
}
}, '编辑'),
h('Button', {
props: {
type: 'error',
size: 'small'
},
style: {
marginRight: '5px'
},
on: {
click: () => {
this.removeButton(params.row)
}
}
}, '删除')
])
}
}
],
data: [],
total: 0, // 总数据
pageQuery: {
nickname: '',
pageNum: 1,
pageSize: 10
},
methods部分:
// 获取用户信息
getUserData() {
const para = {
params: this.pageQuery
}
getUserInfo(para).then(res => {
// 开发按钮转换为布尔值
for (let i = 0; i < res.data.length; i++) {
if (res.data[i].enabled === 1) {
res.data[i].enabled = true
} else {
res.data[i].enabled = false
}
}
this.data = res.data
this.total = res.total
})
},
// 切换冻结启用开关
switchChange(row) {
// 切换开关,该行的数据状态也会跟着切换,直接取该行的状态即可,把布尔值转换为0/1保存
let enable = row.enabled ? 1 : 0
let msg = enable === 1 ? '启用' : '冻结'
this.$Modal.confirm({
title: '提示',
content: `<p>确认${msg}账户吗?</p>`,
onOk: () => {
const para = {
params: {
enabled: enable,
userName: row.userName
}
}
serUserEnable(para).then(res => {
this.$Message.success('设置成功')
this.getUserData()
}).catch(res => {
// 切换不成功也要刷新表格,保持正确状态
this.getUserData()
})
},
onCancel: () => {
this.$Message.info('取消')
}
})
},
// 切换分页触发
changePage(val) {
this.pageQuery.pageNum = val
this.getUserData()
},
// 改变每页条数触发
pageSizeChange(val) {
this.pageQuery.pageSize = val
this.getUserData()
}
注意问题:
1.iview表格实现和elementui的表格实现有点不同,iview采用的是render函数自定义表格中操作,样式,elementui是直接绑定数据和用template的html模板,elementui的这种方式似乎更好理解,render函数看的是在费劲
2.如果有像switch这种组件,在表格中既要操作(有点击事件),又要显示状态(状态随数据库的状态进行变化),不要采用render函数的方式,因为这种方式无法随控制进行刷新表格数据,如上代码所示,我已经注释了,直接用template的方式重新获取数据库数据进行刷新即可。