el-table在弹窗中的使用
概要
在实际的业务场景中,需要在弹窗内增加表格的展示,勾选.本文以我实际的开发过程中,碰到的"坑",来总结一下el-table
如何设置
使用Vue2版本来开发 element-ui
如何展示基本的图表数据,并支持基础的勾选
数据的展示包含多个页面
参考官方的代码
vue
<template>
<div class="main">
<!-- 授权设备 -->
<el-dialog title="选择设备" :visible.sync="deviceOpen" width="500px">
<el-table
ref="multipleTable"
:data="iotDeviceList"
tooltip-effect="dark"
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
label="日期"
width="120">
<template slot-scope="scope">{{ scope.row.date }}</template>
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="120">
</el-table-column>
<el-table-column
prop="address"
label="地址"
show-overflow-tooltip>
</el-table-column>
</el-table>
<pagination
v-show="devicesTotal>0"
:total="devicesTotal"
:page.sync="deviceQueryParams.pageIndex"
:limit.sync="deviceQueryParams.pageSize"
@pagination="getDevicesList"
/>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitDevicesForm">确 定</el-button>
<el-button @click="cancelDevicesSet">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
// 设备设置界面打开
deviceOpen: false,
devicesTotal: 0,
deviceQueryParams: {
pageIndex: 1,
pageSize: 10
deviceType: undefined
},
iotDeviceList: [{
date: '2016-05-03',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
date: '2016-05-08',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}],
multipleSelection: []
}
},
methods: {
// 提交设备设置
submitDevicesForm(){
var form = {...}
updateIoDevice(form).then(response => {
if(response.code === 200){
// 上方会显示成功的消息通知
this.msgSuccess(response.msg)
this.deviceOpen = false
this.deviceLoading = false
// 此处相当于弹窗取消之后,重新刷新页面数据
this.getList()
}else {
this.msgError(response.msg)
}
})
},
// 取消设备设置
cancelDevicesSet(){
this.deviceLoading = false
this.deviceOpen = false
},
// 勾选改变时触发的事件
handleSelectionChange(selection) {
// 每次触发打印selection信息,总是发现出现数组中包含多个toggle数据,所以便再此设置了过滤,如果有同学知道为什么,可以评论区留言
this.multipleSelection = selection.filter((item) => Array.isArray(item) === false).map(obj => obj.id);
this.single = selection.length !== 1
this.multiple = !selection.length
},
// 分页查询请求
getDevicesList(){
this.deviceLoading = true
listIotDevice(this.deviceQueryParams).then(response => {
this.iotDeviceList = response.data.lise
this.deviceTotal = response.data.count
})
}
}
}
</script>
以上代码只实现了基本的单页面勾选功能,未实现真正意义上的多页面勾选,页面切换。想要实现,请看一下介绍
如何支持跨页依然能保留记录的功能
- el-table 添加
row-key
<el-table v-loading="deviceLoading" ref="multipleTable" :row-key="getRowKeys"
- el-table-column 添加
reserve-selection
<el-table-column type="selection" :reserve-selection="true" width="55" align="center"/>
- 修改getDevicesList函数,保证在切换Page的时候,自动勾选之前的选项
javascript
...
this.iotDeviceList = response.data.list
this.devicesTotal = response.data.count
// 执行回显操作
this.$nextTick(() => {
let selectItem = []
this.iotDeviceList.forEach(item =>{
if (this.devicesIds){
this.devicesIds.forEach(id => {
if (item.id === id){
selectItem.push(item)
}
})
}
})
// 触发勾选项
this.$refs.multipleTable.toggleRowSelection(selectItem)
})
-
增加getRowKeys,保证每一个行的数据是唯一
jsmethods: { getRowKeys(row){ return row.id } }
-
注意,在关闭dialog之后,点击确定,点击取消的时候,需要清理一下
selection
如果不清理,目前观察toggle数据会不断增长
this.$refs.multipleTable.clearSelection()
如何实现从后端记录的勾选在前端显示
基本思路是这样: 从后端获取之前勾选的device ID之后, 在每次页面获取数据后,触发勾选,但是如果勾选成功后,记录要删除,否则用户点击取消以前的数据,则是无效的
javascript
this.$nextTick(() => {
....
})
// 承接上面的代码,下面是实际读取后端数据触发toggle的操作
this.$nextTick(() => {
// let selectItem = []
let remove_ids = []
this.iotDeviceList.forEach(item =>{
// 记录从数据库获取的数据, beforeDevicesIds是之前勾选的设备id列表
if (this.beforeDevicesIds){
this.beforeDevicesIds.forEach(id => {
if (item.id === id){
remove_ids.push(id)
this.$refs.multipleTable.toggleRowSelection(item)
}
})
}
})
if (remove_ids.length === 0){
}else{
// 过滤已经处理devices ID
this.beforeDevicesIds = this.beforeDevicesIds.filter(id =>!remove_ids.includes(id))
}
}) // 因为页面渲染的异步,所以加一个延迟刷新数据
this.deviceLoading = false
知识点
Vue有个异步更新策略,就是如果数据变化,vue不会立刻更新DOM,而是开启一个队列,把组件更新函数保存到队列中,在同一事件循环中发生的所有数据变更会异步的批量更新。如果想获取更新后的DOM状态,需要使用nextTick
使用场景:
- 等待DOM更新完成
- 避免布局抖动,比如多次数据更新
- 获取更新后的DOM