本文正在参加「金石计划」
场景
Popover 弹出框 其实在我们的项目中,有很多使用场景。比如:
- 在小图旁边预览大图
- 点击某个内容,展示详情或者扩展内容
- 点击删除等按钮进行二次确认
- hover 某个内容,展示其隐藏内容等
弹出框的位置可以出现在其周边各个位置。
多 el-popover 怎么处理?
需求:就是需要在列表的每一项里边都展示出 el-popover;或者是在 表格里边 嵌套 el-popover;同一个页面或者同一个模块里边多处需要使用到 el-popover ......
如果我们每一处都使用一份 el-popover,数据量大的时候,或者使用多的话,就会造成卡顿,你不妨试试?!
解决办法:多处共用一份 el-popover。那怎么具体做呢?
el-popover 提供了一个虚拟触发的功能,可以将触发内容和下拉内容分开,那这样就可以只用一个 popover 组件去涵盖所有需要用到的场景。
vue2
不废话了,上代码:
// popover 弹出框组件
<el-popover
v-if="showPop_hide"
ref="popover_hide"
:reference="reference_hide"
:append-to-body="false"
placement="right"
width="450"
trigger="click">
<pop-gdp
:analysis-loading="analysisLoading"
:analysis-data="analysisData"
@popPieClick="popPieClick"
@popLineClick="popLineClick"/>
</el-popover>
// 触发 弹框的内容
<div
v-for="(item, index) in showUnselected"
:key="item.index"
:ref="'pop_hide'+index"
:class="analysisActive === 'hide' + index ? 'active' : ''"
@click="analysisClick('hide', item, index)"
>
<div class="show-word_item">
......
</div>
</div>
上处 pop-gdp 组件内容可据判断来具体展示哪一部分内容。
// data 数据
data() {
return {
showPop_hide: false,
reference_hide: {},
termIndex_hide: -1,
}
}
// 核心触发 方法
analysisClick(type, item, index) {
......
this.analysisPop(type, item, index)
......
},
analysisPop(type, item, index) {
if (this['termIndex_' + type] === index && this['showPop_' + type]) {
this.$refs['popover_' + type] && this.$refs['popover_' + type].doClose()
}
this['showPop_' + type] = false
this['reference_' + type ] = this.$refs['pop_' + type + index][0]
this.$nextTick(() => {
// 等待显示的 popover 销毁后再 重新渲染新的 popover
this['showPop_' + type] = true
this['termIndex_' + type] = index
this['termItem_analysis'] = item
this.$nextTick(() => {
// 此时才能获取 refs 引用
this.$refs['popover_' + type].doShow()
})
})
},
以上代码基本就把这个核心都展示全了,大家如果有类似需求,也可以使用该方式。列表、表格、只要是多 el-popover 都可以使用该方式。
效果如图:
自定义指令 v-popover
vue2 还提供了一个自定义指令,我们也可以使用。使用方式如下:
<el-popover
ref="popover-hover"
placement="top-start"
title="标题"
trigger="hover"
content="这是hover 激活。"
>
</el-popover>
<el-button v-popover:popover-hover>hover 激活</el-button>
<el-popover
ref="popover-click"
placement="bottom"
title="标题"
trigger="click"
content="这是click 激活。"
>
</el-popover>
<el-button v-popover:popover-click>click 激活</el-button>
<el-popover
ref="popover-focus"
placement="right"
title="标题"
trigger="focus"
content="focus 激活"
>
</el-popover>
<el-button v-popover:popover-focus>focus 激活</el-button>
<el-popover
ref="popover"
placement="bottom"
title="标题"
trigger="manual"
content="这是一段内容,这是一段内容,这是一段内容,这是一段内容。"
v-model="visible"
>
</el-popover>
<el-button v-popover:popover @click="visible = !visible">
手动激活
</el-button>
vue3
vue3 版本的 el-popover,就注意到这个场景了,给暴露出来该使用方法了,虚拟触发:
像 Tooltip 一样,Popover 可以由虚拟元素触发,这个功能就很适合使用在触发元素和展示内容元素是分开的场景。通常我们使用 #reference
来放置我们的触发元素, 用 triggering-element
API,您可以任意设置您的触发元素 但注意到触发元素应该是接受 mouse
和 keyboard
事件的元素。
<template>
<el-button ref="buttonRef" v-click-outside="onClickOutside">
Click me
</el-button>
<el-popover
ref="popoverRef"
:virtual-ref="buttonRef"
trigger="click"
title="With title"
virtual-triggering
>
<span> Some content </span>
</el-popover>
</template>
<script setup lang="ts">
import { ref, unref } from 'vue'
import { ClickOutside as vClickOutside } from 'element-plus'
const buttonRef = ref()
const popoverRef = ref()
const onClickOutside = () => {
unref(popoverRef).popperRef?.delayHide?.()
}
</script>
v-popover 将被废弃
Vue3版本 Tips:
v-popover
将被废弃,请使用virtual-ref
作为替代。
您可以使用指令性方式弹出窗口,但这种方法不再推荐 ,因为这使得应用程序变得复杂, 您可以参考虚拟触发来实现一样的效果。
<template>
<el-button
v-popover="popoverRef"
v-click-outside="onClickOutside"
>Click me</el-button>
<el-popover
ref="popoverRef"
trigger="click"
title="With title"
virtual-triggering
persistent
>
<span> Some content </span>
</el-popover>
</template>
<script setup lang="ts">
import { ref, unref } from 'vue'
import { ClickOutside as vClickOutside } from 'element-plus'
const buttonRef = ref()
const popoverRef = ref()
const onClickOutside = () => {
unref(popoverRef).popperRef?.delayHide?.()
}
</script>
小结
本文重点介绍的是 多 el-popover 的使用方式,确实我们的业务场景会遇到,以至于 element-plus 版本都直接把该方法当作官方文档提供出来了。希望能帮助到大家!
最近比较迷恋自定义指令,所以在本文也是提了一嘴自定义指令 v-popover 的使用方式,后续有时间的话,再给大家分享一下最近的自定义指令合集。