<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="Vue.2.6.10.js"></script>
</head>
<body>
<div id="app1" v-cloak>
<div class="main" v-clickoutside="handleClose">
<button @click="show =!show">点击显示下拉菜单</button>
<div class="dropdown" v-show="show">
<p>点击下拉框内容,点击外部区域关闭</p>
</div>
</div>
</div>
</body>
<script>
Vue.directive('clickoutside',{
bind:function(el,binding,vnode){
function documentHandler(e){
if(el.contains(e.target)){
return false;
}
if(binding.expression){
binding.value(e);
console.log(arguments);//e在click时传入的嗷
}
}
el._vueClickOutside_ = documentHandler;
document.addEventListener('click',documentHandler);
},
unbind:function(el,binding){
document.removeEventListener('click',el._vueClickOutside_);
delete el._vueClickOutside_;
}
});
var app1 = new Vue({
el:"#app1",
data:{
show:false
},
methods: {
handleClose:function(){
this.show = false;
console.log(arguments);
}
},
});
//逻辑分析:
//第一次点击按钮,show=true,显示目标区域
//要实现点击外部区域关闭,就要在document上绑定函数,这个指令绑定到实例时
//还绑定了documentHandle函数,如果点击的区域在指令所在的元素内部(e.target来判断
//要注意的是这个e是在执行document.addEL这里传入的),在则跳出
//否则继续往下,第二个判断当前指令有无表达式,点击外部区域后应该执行用户表达式中的函数
//,这里即执行了methods中指定的函数
//使用_vCO_引用了documentHandler,就可以在unbind钩子里移除对document的事件监听函数
//梳理:点击外部区域--触发documentHandler,同时将点击参数传给它(MouseEvent)--判断发现目标区域不包含点击区域--
//--binding.value(e),即handleClose(e)---在methods中这个方法将show属性定义为false--关闭目标区域
</script>
</html>