在源码里会通过 popperElm 进行判断:
if (!vnode || !vnode.context || !mouseup.target || !mousedown.target || el.contains(mouseup.target) || el.contains(mousedown.target) || el === mouseup.target || (vnode.context.popperElm && (vnode.context.popperElm.contains(mouseup.target) || vnode.context.popperElm.contains(mousedown.target)))) return;如果 popperElm 包含鼠标点击的 dom 则跳出逻辑。
然后我又想到了一个问题,popperElm 只能设置一个,当有多个选择栏组件时,还是会出现上面所说的情况。我的想法是,把 clickoutside 给 copy 一份下来,把 popperElm 改成可以接受数组类型,判断时去循环判断,这样应该可以解决问题。
还有一件有趣的事,我在全局搜索时发现 element-ui 里好像没有用到这个指令。
结语clickoutside 不止抽屉的场景,只要你想在点击某个元素区域之外做些事情,都可以考虑它。
除了这个,还有很多优秀的第三方指令,例如 element-ui 中的 v-loading 可以实现局部的加载动画,常用的 vue-lazyload 中的 v-lazy 可以实现图片的懒加载。
个人认为指令属于那种用得少但很实用的东西,可能在开发功能时都没有考虑到用指令来实现,如果你还不了解指令,赶快学起来。