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函数。