项目场景:
使用表格组件时,每行数据都有展开项功能,每个展开项中又是一个表格,这些二级表格有勾选功能,当我勾选第一个展开表格数据后,再勾选第二个展开表格,要求清空第一次勾选的数据。 具体场景如下:问题描述:
- 我先勾选第一个二级表格中的2条数据
- 然后,我再勾选第二个二级表格中的1条数据,没办法清空前2条数据
- 难点:二级表格是隔离的组件,无法在一级表格组件中用 this.$refs 来引用当前操作的二级表格
解决方案:
- 创建一个事件中心 bus,并在二级表格组件中引入
- 在二级表格组件的 created 函数中监听一个事件
- 在二级表格组件的 beforeDestroy 函数中注销该事件
- 在二级表格组件中会有勾选项改变事件,在此发送这个事件
- 完成二级表格勾选项互斥功能
具体代码如下:
<!-- template模版部分 -->
<!-- 大家无需关心组件名,<bk-table>相当于<el-table>,而handleSelectChange是表格勾选项改变时触发的事件 -->
<bk-table ref="progressTableRef" :data="data" @selection-change="handleSelectChange">
<bk-table-column type="selection"></bk-table-column>
<bk-table-column label="所属实例"></bk-table-column>
</bk-table>
// js 脚本部分
props: {
// 一级表格传进来的唯一标识
process: {
type: String,
default: ''
}
},
data() {
return {
// 是否为其他组件发过来的事件
isEmitByOthers: false
},
created() {
// 监听事件
Bus.$on('process-selection-change', this.handleProcessSelectionChange)
},
beforeDestroy() {
// 注销事件
Bus.$off('process-selection-change', this.handleProcessSelectionChange)
},
methods: {
// process-selection-change 事件
handleProcessSelectionChange(process) {
// 如果接收到的唯一标识,就是正在勾选的二级表格, 不做操作
if (process === this.process) return false
// 否则,说明该表格应该要被清空
this.isEmitByOthers = true
// 此处是清空事件,根据不同的UI库,表格的清空事件不一样,具体还得看你使用的UI库文档
this.$refs.progressTableRef.clearSelection()
this.$nextTick(() => {
// 最后需要还原该判别属性
this.isEmitByOthers = false
})
},
// 勾选项变化时触发, 这个list是当前勾选项列表,UI库组件自带
handleSelectChange(list) {
// 如果是自己发出的事件
if (!this.isEmitByOthers) {
// 把当前这个二级表格的数据传给外层父组件
this.$emit('select-change', list)
// 发送一个事件, 并把自己的唯一标识传过去
Bus.$emit('process-selection-change', this.process)
}
}
}
原理:
2发出事件后,bus做出转发动作,接着1,2,3,4,分别做出自己的响应动作,独立完成自己的事件