iview clickoutside指令

clickoutside指令介绍

iview里面有个clickoutside指令,用来处理点击元素外面的事件。

比如在cascader组件里的最外层div就用到了该指令

1
<div :class="classes" v-clickoutside="handleClose">

当用户点击了这个元素的外面,就会执行传到指令中的handleClose函数。

clickoutside指令原理

首先来看一下该指令的源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export default {
bind (el, binding, vnode) {
function documentHandler (e) {
if (el.contains(e.target)) {
return false;
}
if (binding.expression) {
binding.value(e);
}
}
el.__vueClickOutside__ = documentHandler;
document.addEventListener('click', documentHandler);
},
update () {

},
unbind (el, binding) {
document.removeEventListener('click', el.__vueClickOutside__);
delete el.__vueClickOutside__;
}
};

定义了bind和unbind两个钩子函数。

有关Vue自定义指令钩子函数的知识参照官方文档

bind

在bind函数中,给使用了该指令的元素添加了一个__vueClickOutside__属性。

然后在document上绑定了一个click事件,documentHandler

该handler做了两件事:

  1. 判断使用指令的元素中是否包含当前被点击的元素,如果是,说明用户点击的是元素里面,则return false停止事件冒泡
  2. 判断使用指令的元素是否有绑定值,若有,则调用绑定的函数。

需要注意的是,绑定的值必须是一个函数,例如,上述cascader组件中的handleClose就必须是一个函数

因为binding.value(e)在此例中就相当于handleClose(e)binding.value为指令的绑定值,在这里绑定了handleClose这个值)

unbind

解绑,两个操作

  1. 移除监听器,在bind中定义的el.__vueClickOutside__在这里作为removeEventListener的listener参数
  2. 删除元素上的__vueClickOutside__属性