天天看点

vue中点击空白处隐藏div的实现(用自定义指令优雅的实现)

vue中点击空白处隐藏div的实现(用自定义指令优雅的实现)

简单想应该怎么实现?

1、肯定是给document增加一个click事件监听

2、当发生click事件的时候判断是否点击的当前对象

结合着本思路和指令咱们来实现。

代码实现

<template>
    <div>
        <div class="show" v-show="show" v-clickoutside="handleClose">
            显示
        </div>
    </div>
</template>

<script>
const clickoutside = {
    // 初始化指令
    bind(el, binding, vnode) {
        function documentHandler(e) {
            // 这里判断点击的元素是否是本身,是本身,则返回
            if (el.contains(e.target)) {
                return false;
            }
            // 判断指令中是否绑定了函数
            if (binding.expression) {
                // 如果绑定了函数 则调用那个函数,此处binding.value就是handleClose方法
                binding.value(e);
            }
        }
        // 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
        el.__vueClickOutside__ = documentHandler;
        document.addEventListener('click', documentHandler);
    },
    update() {},
    unbind(el, binding) {
        // 解除事件监听
        document.removeEventListener('click', el.__vueClickOutside__);
        delete el.__vueClickOutside__;
    },
};
export default {
    name: 'HelloWorld',
    data() {
        return {
            show: true,
        };
    },
    directives: {clickoutside},
    methods: {
        handleClose(e) {
            this.show = false;
        },
    },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.show {
    width: 100px;
    height: 100px;
    background-color: red;
}
</style>
           

简单介绍vue指令

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

unbind:只调用一次,指令与元素解绑时调用。

接下来我们来看一下钩子函数的参数 (即 el、binding、vnode 和 oldVnode)。

vue中点击空白处隐藏div的实现(用自定义指令优雅的实现)

注意:有时候自己写的弹窗无法点击遮罩层隐藏弹窗。这时我们可以这么做:

1:设置一个盒子跟弹出的窗口平级,然后设置宽高等于遮罩层的,设置 position: absolute; 它的层级小于弹出窗口的层级

2:给弹出的窗口设置成

position: relative;

<div v-if="quitdia" class = "cov"  v-clickoutside="handleClose2">
        <div class = "con create_dialog" style="height:400px;">
            <p class = "ptitle">淘汰候选人 <i @click="hideModel2" class="el-icon-close closes_s"></i></p>
             <div class="rescs beires" style="height:220px;">
                <el-form :model="cerateList"  ref="cerateList" id="re_styles reset_styless">
                    <span class="title_quit"><i><img src="../../assets/img/zhiwei/cuowu.png" alt=""></i> 此候选人将被归档到人才库,请选择归档原因</span>
                     <el-form-item label="淘汰原因" style="margin-left:31px;" >
                          <el-select style="width:280px;height:40px;" v-model="text" placeholder="请选择工作经验">
                              <el-option label="胜任力不足" value="0"></el-option>
                              <el-option label="没有回应" value="1"></el-option>
                              <el-option label="淘汰" value="2"></el-option>
                              <el-option label="与公司文化不符合" value="2"></el-option>
                              <el-option label="福利待遇不匹配" value="2"></el-option>
                              <el-option label="待定" value="2"></el-option>
                          </el-select>
                     </el-form-item>
                     <el-form-item label="具体原因(选填)" >
                        <el-input :rows="4" type="textarea" v-model="text" style="width:280px;margin-left:-4px;" placeholder="请输入内容"></el-input>
                     </el-form-item>
               </el-form>
             </div>
            <div slot="footer" class="dialog-footer">
                 <el-button  type="primary" :class="searchBtnClass3" :disabled="searchDisabled3"   style="height:36px;" >保存</el-button>
            </div>  
        </div>
      </div>
      <div class="close_div">  //这个是平级的div,
      </div>