Vue.js用directive判断是否点击当前DOM以外的地方
varHarrie opened this issue · 2 comments
varHarrie commented
Vue 1.x
Vue.directive('clickOutside', {
bind () {
this.onClick = (event) => {
if (this.el.contains(event.target)) return false
if (this.expression) this.vm[this.expression]()
}
setTimeout(() => {
document.addEventListener('click', this.onClick)
})
},
unbind () {
document.removeEventListener('click', this.onClick)
}
})
Vue 2.x(来自评论)
Vue.directive('clickOutside', {
bind (el, binding, vnode) {
el.event = function (event) {
if (!(el === event.target || el.contains(event.target))) {
vnode.context[binding.expression](event)
}
}
document.body.addEventListener('click', el.event)
},
unbind (el) {
document.body.removeEventListener('click', el.event)
}
})
Vue 3.x
<script>
const vClickOutside = {
mounted(el, binding) {
el.clickOutside = (e) => {
if (el.contains(event.target)) return false
if (typeof binding.value === 'function') binding.value(e)
}
document.addEventListener('click', el.clickOutside)
},
beforeUnmount(el) {
document.removeEventListener('click', el.clickOutside)
}
}
export default {
directives: {
clickOutside: vClickOutside,
},
methods: {
log() {
console.log('click')
}
}
}
</script>
<template>
<div class="rect" v-click-outside="log">click outside</div>
</template>
<style>
.rect {
margin: 50px;
padding: 12px;
display: inline-block;
border: 1px solid black;
user-select: none;
}
</style>
wujunchuan commented
Get it.
Thx
wujunchuan commented
Vue2.0 的自定义指令不再支持this引用,需要对其进行一定程度的改写。
// 自定义指令, 判断当前点击是否在DOM以外的地方
Vue.directive('clickOutside', {
bind (el, binding, vnode) {
el.event = function (event) {
if (!(el === event.target || el.contains(event.target))) {
// call method provided in attribute value
vnode.context[binding.expression](event)
}
}
document.body.addEventListener('click', el.event)
},
unbind (el) {
document.body.removeEventListener('click', el.event)
}
})