# 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 是不用重新加载的。 效果图如下
# 总结
因为时间不能对网上的所有实现都复现,这里只是检索了下,并对排在靠前的方式做了下尝试,学习下他们在遇到这个问题时的处理方式。开阔自己的思维。最重要的是希望官方能解决这个问题。