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

相关推荐
雯0609~16 分钟前
网页F12:缓存的使用(设值、取值、删除)
前端·缓存
℘团子এ19 分钟前
vue3中如何上传文件到腾讯云的桶(cosbrowser)
前端·javascript·腾讯云
学习前端的小z25 分钟前
【前端】深入理解 JavaScript 逻辑运算符的优先级与短路求值机制
开发语言·前端·javascript
星星会笑滴28 分钟前
vue+node+Express+xlsx+emements-plus实现导入excel,并且将数据保存到数据库
vue.js·excel·express
彭世瑜1 小时前
ts: TypeScript跳过检查/忽略类型检查
前端·javascript·typescript
FØund4041 小时前
antd form.setFieldsValue问题总结
前端·react.js·typescript·html
Backstroke fish1 小时前
Token刷新机制
前端·javascript·vue.js·typescript·vue
小五Five1 小时前
TypeScript项目中Axios的封装
开发语言·前端·javascript
小曲程序1 小时前
vue3 封装request请求
java·前端·typescript·vue
临枫5411 小时前
Nuxt3封装网络请求 useFetch & $fetch
前端·javascript·vue.js·typescript