Vue指令實現(xiàn)OutClick的示例
原始實現(xiàn)
下面是兩種常見的模態(tài)框的實現(xiàn)方式
方案一:默認 click 都是放在冒泡階段,只要在內容區(qū)域上添加 click 的阻止冒泡即可
<div class="cover" @click="close"> <!-- 阻止冒泡 --> <div class="content" @click.stop>modal content</div> </div>
方案二:通過代碼判斷點擊觸發(fā)的 DOM 是否在內容區(qū)域內
<div class="cover" @click="handleClick">
<div class="content" ref="content">modal content</div>
</div>
handleClick (e) {
let clickOut = true
let temp = e.target
do {
if (temp === this.$refs.content) {
clickOut = false
break
}
temp = temp.parentElement
} while (temp !== document.documentElement)
console.log(clickOut)
}
指令實現(xiàn)
上面的代碼可以解決全屏的模態(tài)框點擊外部區(qū)域關閉。但是還有一種 Pop 的彈出,這種彈出的外部區(qū)域不在本組件內,想要實現(xiàn)這種彈出的點擊外部區(qū)域關閉用上面的方式二也是可以的,只需把 mounted 階段把 handleClick 事件添加到 body,在 beforeDestroy 上解綁 body 上的點擊時間就就可以了。
如果多個組件需要實現(xiàn)這點擊外部區(qū)域關閉的效果,可以通過 Vue 的指令來進行封裝
實現(xiàn)彈窗
<div class="cover"> <div class="content" v-out-click="close">modal content</div> </div>
實現(xiàn)彈出
<button @click="popIsShow = true">顯示氣泡</button> <div class="pop" v-if="popIsShow" v-out-click="closePop">I'm pop text</div>
指令代碼的具體內容如下。有一點比較難受的是指令里面沒有地方能存放變量,只好把把這些變量放到了 DOM 上了。還有就是在使用的時候要加上v-的前綴,指令的名字不用帶上v-
import outClick from './directive/out-click.js'
Vue.directive(outClick.name, outClick)
const KEY_OUT = '_out_click'
const KEY_OUT_EVENT = '_out_click_event'
const KEY_IN = '_in_click'
const KEY_FLAG = '_in_out_flag'
function removeEvent(el, binding, vnode) {
el.removeEventListener('click', el[KEY_IN], false)
window.removeEventListener('click', el[KEY_OUT], false)
delete el[KEY_IN]
delete el[KEY_OUT]
delete el[KEY_OUT_EVENT]
delete el[KEY_FLAG]
}
function initEvent(el, binding, vnode) {
// setTimeout 0: 忽略點擊外部的按鈕初始化該組件時,觸發(fā)的origin click
setTimeout(() => {
el[KEY_OUT] = () => outClick(el)
el[KEY_IN] = () => inClick(el)
el[KEY_OUT_EVENT] = binding.value
el.addEventListener('click', el[KEY_IN], false)
window.addEventListener('click', el[KEY_OUT], false)
}, 0)
}
function inClick(el) {
// 通過事件捕獲的順序作為標志位
// 最好不要使用阻止冒泡來實現(xiàn),那樣會影響其他的click無法觸發(fā)
el[KEY_FLAG] = '1'
}
function outClick(el) {
if (!el[KEY_FLAG] && el[KEY_OUT_EVENT]) {
el[KEY_OUT_EVENT]()
}
delete el[KEY_FLAG]
}
export default {
name: 'out-click',
update: (el, binding, vnode) => {
if (binding.value === binding.oldValue) {
return
}
removeEvent(el, binding, vnode)
initEvent(el, binding, vnode)
},
bind: initEvent,
unbind: removeEvent
}
以上就是Vue指令實現(xiàn)OutClick的示例的詳細內容,更多關于Vue指令實現(xiàn)OutClick的資料請關注腳本之家其它相關文章!
相關文章
vue+iview框架實現(xiàn)左側動態(tài)菜單功能的示例代碼
這篇文章主要介紹了vue+iview框架實現(xiàn)左側動態(tài)菜單功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07
用 Vue.js 遞歸組件實現(xiàn)可折疊的樹形菜單(demo)
通過本文給您演示一下如何有效地使用遞歸組件,我將通過建立一個可擴展/收縮的樹形菜單的來一步步進行。下面通過本文給大家分享用 Vue.js 遞歸組件實現(xiàn)可折疊的樹形菜單,需要的朋友參考下吧2017-12-12
Vue3-KeepAlive,多個頁面使用keepalive方式
這篇文章主要介紹了Vue3-KeepAlive,多個頁面使用keepalive方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08

