el-popover在el-table中使用问题记录
记录一下在使用 element UI 中 el-popover 组件在 el-table 中使用出现的问题
在使用element UI 中 el-popover 遇到了下图的确定按钮点击时无法关闭 el-popover。对于这个问题如何解决实现下图点击取消时的关闭 el-popover 效果特定记录下。
起因&原因
因为对前端 node,vue 并不精通,所以本章将用肤浅的表现来说明这个事件
官方的 el-popover 的使用例子。本质是通过 v-model 绑定一个 boolean 值。打开的时候值为true,关闭的时候值为false。但是在 el-table 中使用时却出现 boolean 值已经变成 false 了,可 el-popover 依旧未消失。
<el-popover
placement="top"
width="160"
v-model="visible">
<p>这是一段内容这是一段内容确定删除吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="visible = false">取消</el-button>
<el-button type="primary" size="mini" @click="visible = false">确定</el-button>
</div>
<el-button slot="reference">删除</el-button>
</el-popover>
<script>
export default {
data() {
return {
visible: false,
};
}
}
</script>
解决办法
自己想的方法
在看到下图效果时,确定重复点击打开 el-popover 的按钮可以实现 el-popover 的展示和关闭,并符合模块的自身逻辑
原理就是点击【下架】时打开 el-popover 同时将自身 Dom 节点元素放置到 scope 下。在点击【取消】或者【确定】时获取 Dom 节点通过 js 触发【下架】的点击事件。这个实现在 el-table-column 有 fixed 属性的时候依旧有效。
<!-- table表格下的关键代码 -->
<el-table-column fixed="right" label="操作" width="130">
<template slot-scope="scope">
<div>
<el-popover
placement="top"
width="160">
<p>你确定要下架该接口吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="test(scope.eventd)">取消</el-button>
<el-button type="primary"size="mini"@click="test(scope.eventd)">确定</el-button>
</div>
<el-button slot="reference" type="text" size="small" @click="scope.eventd = $event">下架</el-button>
</el-popover>
<el-button type="text" size="small">上架</el-button>
<el-button type="text" size="small">删除</el-button>
</div>
</template>
</el-table-column>
<!-- methods 下的 test方法 -->
<script>
export default {
methods: {
test(a){
// 除了 path的第一个元素还有a.srcElement.click();也是可以的,但这个方法面临废弃
a.path[0].click();
}
}
}
</script>
问题解决后就看了看网上的一下实现方法。
通过 el-popover 的:ref实现
实现原理:通过设置 ref 找到 el-popover 再调用关闭方法
实现代码如下
<!-- table表格下的关键代码 -->
<el-table-column label="操作" width="130">
<template slot-scope="scope">
<div>
<el-popover
placement="top"
width="160"
:ref="'popover'+scope.$index">
<p>你确定要下架该接口吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="test(scope.row,scope.$index)">取消</el-button>
<el-button type="primary" size="mini" @click="scope._self.$refs[`popover${scope.$index}`].doClose()">确定</el-button>
</div>
<el-button slot="reference" type="text" size="small">下架</el-button>
</el-popover>
<el-button type="text" size="small">上架</el-button>
<el-button type="text" size="small">删除</el-button>
</div>
</template>
</el-table-column>
<!-- methods 下的 test方法 -->
<script>
export default {
methods: {
test(row, index) {
let s = 'popover' + index;
console.log(this.$refs[s]); // 此处打印后续验证
this.$refs[s].doClose();
}
}
}
</script>
因为并不是很懂 ref 这个元素属性的作用。但在测试中发现在 el-table-column 有 fixed 属性的时候无效。一下是对比图,第一个是不加 fixed,第二个是加了 fixed的时候
通过第二张图可以看出因为 el-table-column 有 fixed 属性,导致 table 表格中的操作这列有一个原本的列,和一个固定的列,而点击取消时获取到的【下架】并不是点击打开是的【下架】按钮。所以点击失效了。
通过 v-show 实现
实现原理:默认所有的 v-popover 全部加载,再通过 v-show 实现展示控制
实现代码如下
<!-- table表格下的关键代码 -->
<el-table-column fixed="right" label="操作" width="130">
<template slot-scope="scope">
<div>
<el-popover
placement="top"
width="160"
v-model="popoverShow"
v-show="popoverId == scope.$index">
<p>你确定要下架该接口吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="popoverId = -1">取消</el-button>
<el-button type="primary" size="mini" @click="popoverId = -1">确定</el-button>
</div>
</el-popover>
<!-- 重点!! 下架按钮放置在 el-popover 之后 -->
<el-button type="text" size="small" @click="popoverId = scope.$index;">下架</el-button>
<el-button type="text" size="small">上架</el-button>
<el-button type="text" size="small">删除</el-button>
</div>
</template>
</el-table-column>
<!-- data 下的 popoverShow 和 popoverId值-->
<script>
export default {
data() {
return {
popoverId: -1,
popoverShow: true,
}
}
}
</script>
经测试使用 v-show 实现在el-table-column 有 fixed 属性时依旧有效,但 v-popover 弹窗所在的位置会有一定的偏移,因为 v-popover 窗口在加载时会调整位置,而通过 v-show 是不用重新加载的。 效果图如下
总结
因为时间不能对网上的所有实现都复现,这里只是检索了下,并对排在靠前的方式做了下尝试,学习下他们在遇到这个问题时的处理方式。开阔自己的思维。最重要的是希望官方能解决这个问题。