Vue自定义指令-点击内容框以外的地方,自动隐藏起内容框

在这里插入图片描述

自定义指令

 directives: {
    'click-outside': {
      bind: function (el, binding, vnode) {
        console.log('el',el);
        el.event = function (event) {
          // 检查点击是否发生在节点之内(包括子节点)
          if (!(el == event.target || el.contains(event.target))) {
            // 如果没有,则触发调用
            // 若绑定值为函数,则执行
            // 这里我们可以通过钩子函数中的 vnode.context,来获取当前组件的作用域
            if (typeof vnode.context[binding.expression] == 'function') {
              vnode.context[binding.expression](event)
            }
          }
        }
        // 绑定事件
        // 设置为true,代表在DOM树中,注册了该listener的元素,会先于它下方的任何事件目标,接收到该事件。
        document.body.addEventListener('click', el.event, true)
      },
      unbind: function (el) {
        // 解绑事件
        document.body.removeEventListener('click', el.event, true)
      },
    },
  },

完整使用

<template>
  <div>
    <!-- 这是基于 bootstrap 常见的下拉菜单样式 -->
    <div class="row" style="margin-left: 20px;">
      <label class="mr5" style="font-size: 14px;">下拉菜单</label>
      <!-- v-click-outside 绑定方法名 -->
      <div class="btn-group" v-click-outside="closeMenu">
        <!-- 这里点击会切换菜单是否可见 -->
        <button
          type="button"
          class="btn btn-default dropdown-toggle"
          @click="isMenuShown = !isMenuShown"
        >
          点击 <span class="caret"></span>
        </button>
        <ul v-show="isMenuShown" class="dropdown-menu" style="display:block;">
          <li><a href="#">Action</a></li>
          <li><a href="#">Another action</a></li>
          <li><a href="#">Something else here</a></li>
          <li role="separator" class="divider"></li>
          <li><a href="#">Separated link</a></li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        isMenuShown: false
      };
    },
    directives: {
	    'click-outside': {
	      bind: function (el, binding, vnode) {
	        console.log('el',el);
	        el.event = function (event) {
	          // 检查点击是否发生在节点之内(包括子节点)
	          if (!(el == event.target || el.contains(event.target))) {
	            // 如果没有,则触发调用
	            // 若绑定值为函数,则执行
	            // 这里我们可以通过钩子函数中的 vnode.context,来获取当前组件的作用域
	            if (typeof vnode.context[binding.expression] == 'function') {
	              vnode.context[binding.expression](event)
	            }
	          }
	        }
	        // 绑定事件
	        // 设置为true,代表在DOM树中,注册了该listener的元素,会先于它下方的任何事件目标,接收到该事件。
	        document.body.addEventListener('click', el.event, true)
	      },
	      unbind: function (el) {
	        // 解绑事件
	        document.body.removeEventListener('click', el.event, true)
	      },
	    },
    },
    methods: {
      // 该方法将菜单是否可见设置为不可见
      closeMenu(ev) {
        console.log({ ev });
        this.isMenuShown = false;
      }
    }
  };
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值