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>

打印得出结果:

b894c5a004ac4a4689309023af5f8e48.png

 

我们需要的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函数。

 

更多推荐