el-popover个性化关闭
需求:手动关闭弹窗。点击非点踩区域关闭popover(包括点击空白处关闭)
原官网组件:设置 :visible 手动关闭弹窗后,无法点击空白处关闭弹窗。需个性化修改
关键代码:
1)点击非点踩区域可以引入element-plus的方法ClickOutside
1.引入ClickOutside方法和vue3的ref函数以便响应式操作showPopover
import { ClickOutside as vClickOutside } from "element-plus";
import { ref } from "vue";
const showPopover = ref(false); // 手动显示隐藏popover弹窗
const evaluateText = ref('')
2.el-popover设置手动关闭,给点踩元素绑定vClickOutside方法
<el-popover placement="bottom" :width="400" :visible="showPopover">
<template #reference>
<div class="item">
<img src="@/assets/icons/diancai.png" @click="showPopover = true;"
v-click-outside="onClickOutside" />
</div>
</template>
<template #default>
<div class="popover-close" @click="showPopover = false">
<el-icon><Close /></el-icon>
</div>
<div class="popover-content">
<el-input
class="popover-con-textarea"
rows="3"
v-model="evaluateText"
maxlength="20"
placeholder="请输入您的宝贵意见"
type="textarea"
/>
<el-button @click="showPopover = false">提交反馈</el-button>
</div>
</template>
</el-popover>
3.设置onClickOutside方法点击空白区域,关闭弹窗
const onClickOutside = (e: any) => {
showPopover.value = false;
}
2)出现问题:点击弹窗区域也会关闭,如果弹窗区域需要进行表单操作,则不符合需求。
目标:点击弹窗区域不能关闭。思路:如果点击区域不是弹窗区域节点才关闭,获取弹窗区域节点。
知识点1:vue3如何访问dom节点
和vue2一样,通过ref绑定要访问的dom节点。但vue3需要先用ref函数来初始化,不同于vue2 this.$refs.xx访问。
<script setup lang="ts">
import { ref } from "vue";
const mydom = ref(null);
onMounted(() => { // 需要在DOM加载完毕之后才可获取到
console.log(mydom.value)
})
</script>
<template>
<div ref="mydom">我是节点</div>
</template>
如果绑定在自己写的dom节点(如),可用上述方法访问。
但是访问element-plus标签的节点,则需参考官网文档的方法代码:虚拟触发
贴出官方关键代码,需要unref函数处理。不能像自己写的节点.value获取
unref(popoverRef).popperRef?.delayHide?.()
<script setup lang="ts">
import { ref, unref } from 'vue'
const popoverRef = ref(null);
onMounted(() => { // 需要在DOM加载完毕之后才可获取到
console.log(unref(popoverRef),'第一层')
})
</script>
<template>
<el-popover
ref="popoverRef"
>
<span> Some content </span>
</el-popover>
</template>
打印得出结果:
我们需要的dom节点在contentRef下。注意:通过观察,并且我这里是按基础用法使用组件(非虚拟出发),并官网的没有delayHide方法,只能设置showPopover = false来关闭。
最后点击空白处关闭的方法:
const onClickOutside = (e: any) => {
if (showPopover.value && !unref(popoverRef).popperRef.contentRef.contains(e.target)) {
showPopover.value = false;
}
}
3)完整代码
<script setup lang="ts">
import { ref, unref } from 'vue'
import { ClickOutside as vClickOutside } from "element-plus";
const showPopover = ref(false);
const evaluateText = ref('');
const popoverRef = ref();
const onClickOutside = (e:any) => {
if(showPopover.value && !unref(popoverRef).popperRef.contentRef.contains(e.target)) {
showPopover = false;
}
}
</script>
<template>
<el-popover placement="bottom" :width="400" :visible="showPopover" ref="popoverRef">
<template #reference>
<div class="item">
<img src="@/assets/icons/diancai.png" @click="showPopover = true;"
v-click-outside="onClickOutside" />
</div>
</template>
<template #default>
<div class="popover-close" @click="showPopover = false">
<el-icon><Close /></el-icon>
</div>
<div class="popover-content">
<el-input
class="popover-con-textarea"
rows="3"
v-model="evaluateText"
maxlength="20"
placeholder="请输入您的宝贵意见"
type="textarea"
/>
<el-button @click="showPopover = false">提交反馈</el-button>
</div>
</template>
</el-popover>
</template>
4)总结
1.属性:visible 手动关闭el-popover。
2.点击页面除了某个元素的空白处的方法,可以借助element-plus的ClickOutside方法。
<div class="item" @click="show = true" v-click-outside="onClickOutside">打开弹窗</div>
3.vue3访问dom节点方法。
4.vue3访问自己写的dom节点 可以直接mydom.value访问,但是访问el-popover节点是有区别的,需要unref函数。