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)。
注意:有时候自己写的弹窗无法点击遮罩层隐藏弹窗。这时我们可以这么做:
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>