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中的打印值:

相关推荐
Misnice8 分钟前
shadcn如何使用
前端·reactjs
h_jQuery12 分钟前
vue使用gm-crypto对数据进行sm4加密处理
前端·javascript·vue.js
阿赛工作室1 小时前
Vue中onBeforeUnmount不触发的解决方案
前端·javascript·vue.js
码王吴彦祖1 小时前
顶象 AC 纯算法迁移实战:从补环境到纯算的完整拆解
java·前端·算法
小叶lr1 小时前
jenkins打包前端样式丢失/与本地不一致问题
运维·前端·jenkins
浩星1 小时前
electron系列1:Electron不是玩具,为什么桌面应用需要它?
前端·javascript·electron
ZC跨境爬虫1 小时前
Scrapy工作空间搭建与目录结构解析:从初始化到基础配置全流程
前端·爬虫·python·scrapy·自动化
小村儿1 小时前
连载04-最重要的Skill---一起吃透 Claude Code,告别 AI coding 迷茫
前端·后端·ai编程
_院长大人_2 小时前
Vue + ECharts 实现价格趋势分析图
前端·vue.js·echarts
疯笔码良2 小时前
【Vue】自适应布局
javascript·vue.js·css3