vue点击容器外隐藏元素(点击非本身以外的部分隐藏元素)

如图点击蓝色边框以外任意地方隐藏蓝色边框容器(不使用输入框的失焦事件)

实现思路:

获取到dom节点然后通过其contains方法来判断点击的地方是否为其子元素或其本身

原生js获取dom跟vue的$el都可以实现

也可以通过vue的this.refs.showBoxRef.el.contains()

注意事项:

1.如果不是在非必要的情况下可以使用v-show,这样就不会有dom渲染先后顺序的问题

2.记得在添加事件的时候传第三个参数阻止冒泡,不然点击本身的时候也会触发事件导致其无法显示,也可以在显示事件添加.stop来阻止冒泡

3.添加完事件记得要移除事件

4.一定主要注意在获取dom的时候看dom有没有渲染,不要在mounted之前的生命周期操作dom以及v-if值为false的元素

5.不要直接使用this.$refs'refName'否则就会报下面的错,

Uncaught TypeError: this.$refs.showBoxRef.contains is not a function
at VueComponent.isClick

javascript 复制代码
<template>
  <div class="child-task-page">
    <Button icon="ios-add" type="dashed" size="small" @click="add" ref="buttonRef">显示</Button>
    <Row>
      <Col
        span="24"
        v-if="showBox"
        class="add-box"
        ref="showBoxRef"
        id="showBoxId"
      >
        <Checkbox v-model="curObj.check"></Checkbox>
        <Input v-model="curObj.value" :border="false" placeholder="请输入" />
      </Col>
    </Row>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showBox: false,
      curObj: {
        check: false,
        name: "",
      },
    };
  },
  mounted () {
    console.log(this.$el,'this');//直接this.$el可以获取到当前的dom节点,跟原生js获取的dom节点一样
    console.log(this.$refs.buttonRef.$el,'showBoxRef');//this.$refs['refname']获取的是组件包含vue的一些属性,再.$el才是具体的dom节点
    console.log(this.$refs.buttonRef.$el.contains,'contains');//获取到dom节点后就可以使用contains方法了
  },
  beforeDestroy() {
    document.removeEventListener("click", this.isClick); //页面销毁的时候移除事件
  },
  methods: {
    add() {
      //往document身上添加点击事件,
      // 参数一:事件类型
      // 参数二:事件执行的函数
      // 参数三:指定事件是否在捕获或冒泡阶段执行。
      this.showBox = true;
      this.$nextTick(() => {
        // 加个this.$nextTick使dom更新后再执行获取dom的方法(在这里实际上没有用,改获取不到的还是获取不到,但不影响功能)
        document.addEventListener("click", this.isClick, true);
      });
      
    },
    isClick(e) {
        console.log(
          document.getElementById("showBoxId"),
          'document.getElementById("showBoxId")'
        );
        let isSelf = document.getElementById("showBoxId"); //获取dom元素
        if (isSelf) {
          //判断一下dom元素有没有获取成功
          if (!isSelf.contains(e.target)) {
            //通过dom元素的contains方法传入目标元素,containsf方法返回一个布尔值
            // 如果点击的是元素本身或者其子元素则返回true,否则返回false
            this.showBox = false;
          }
        }
    },
  },
};
</script>

<style scoped lang="less">
.add-box {
  display: flex;
  border: 1px solid #2d8cf0;
  border-radius: 3px;
  padding: 10px;
}
</style>

mounted中的打印值:

相关推荐
一颗烂土豆13 分钟前
ECharts 太平面?试试这款 Vue 3D 图表库
前端·vue.js·echarts
anyup21 分钟前
迁移uni-app x,我是如何让 AI 把我一步步搞崩溃的...
前端·uni-app·trae
用户9210802628629 分钟前
从读框架到搭项目:基于 Ant Design X Vue 和 RICH 范式搭建 AI 前端工作台
前端
Hilaku30 分钟前
为什么同一段代码在 Safari 上永远有 Bug?
前端·javascript·程序员
半仙er35 分钟前
第二周06天 Vue3 + TypeScript 实战与本周复盘
前端
heyCHEEMS37 分钟前
切页回来组件消失了?一个浏览器渲染机制引起的容器高度坍塌 bug
前端·浏览器
iaku38 分钟前
Prompt 不是玄学:写给前端的 Prompt 工程指南
前端·人工智能
爱丶不疚38 分钟前
在 dsh 仓库里扒到的宝藏工作流:详解 .agents/notes 决策沉淀系统
前端·agent·vibecoding
喜欢睡觉43 分钟前
从"送花"讲懂 JavaScript:对象、数据类型与代理模式
前端
渣波44 分钟前
NestJS 企业级后端架构实战:从核心代码到工程化思维的深度重构
前端·typescript·nestjs