鼠标移入到元素之外触发事件

225 阅读1分钟

方法一:(此为js语法)

<template>
  <div class="ButtonDownBox" ref="ButtonDownBox">
    <div class="button" @click="button" ref="button">{{ buttonName }}
      <i class="el-icon-caret-bottom" v-if="iconShow && buttonDownData"></i>
      <i class="el-icon-caret-top" v-if="!iconShow && buttonDownData && buttonDownUnfold"></i>
    </div>
    <div class="buttonDownList" ref="buttonDownList" v-if="buttonDownData && buttonDownUnfold">
      <span @click="everyButton(item)" class="downButton" v-for="item in buttonDownData" :key="item.id">
        {{ item.name }}
      </span>
    </div>
  </div>
</template>

<script>
export default {
  name: 'ButtonDown',
  props: [
    'buttonDownData', // 下拉框内数据
    'buttonName', // 默认名称
    'buttonDownUnfold', // 下拉框是否展开
    'itemId', //点击的整个下拉菜单的id
  ],
  data() {
    return {
      buttonDownShow: false, //定义一个可控制下拉框是否展开的变量
      iconShow: true, //点击下拉时切换图标
    };
  },

  updated() {

  },
  mounted() {
    // 监听鼠标移入到按钮之外关闭下拉框
    document.addEventListener("mousedown", (e) => {
      if (!e.composedPath().includes(this.$refs.ButtonDownBox)) {
        this.buttonDownShow = false;
        this.iconShow = true;
      };
    });
  },
  watch: {
    // 监听按钮控制是否展开下拉框
    buttonDownShow(val) {
      if (this.$refs.buttonDownList) {
        this.$refs.buttonDownList.style.height = val ? (this.buttonDownData.length + 0) * 40 + "px" : 0;
      }
    },
  },
  methods: {
    // 点击展开/收起按钮
    button() {
      this.buttonDownShow = !this.buttonDownShow;
      if (this.buttonDownUnfold) {
        this.iconShow = !this.iconShow;
      }
    },
    // 点击下拉框内的按钮
    everyButton(item) {
      this.buttonDownData.push({}); //解决vue数组不渲染页面问题
      this.buttonDownData.pop(); //解决vue数组不渲染页面问题
      this.$emit('everyButtonName', item.name, this.itemId);
      this.buttonDownShow = false;
    }
  },
};
</script>

方法二:(vue3中创建自定义指令)

methods.js

//自定义组件
export default (app) => {
  // 监听鼠标移入到元素之外触发事件
  app.directive("outside", {
    beforeMount(el, actions) {
      el.outsideFn = (e) => {
        // 判断点击事件是否发生在元素外部
        if (!(el === e.target || el.contains(e.target))) {
          // 如果是外部点击,则执行绑定的函数
          actions.value(e);
        }
      };
      // 在全局添加点击事件监听器
      document.addEventListener("mousedown", el.outsideFn);
    },
    unmounted(el) {
      // 在组件销毁前,移除事件监听器以避免内存泄漏
      document.removeEventListener("mousedown", el.outsideFn);
    },
  });
};

popup.vue

<template>
    <div class="popup1" v-outside="popupOutside">
      <div class="header">
        <span class="title">标题</span>
        <el-icon @click="popupShow1 = false"><Close /></el-icon>
      </div>
    </div>
</template>

<script setup lang="ts">
let popupShow1: Ref = ref(false);
function popupOutside() {
  popupShow1.value = false
}
</script>