Vue指令實(shí)現(xiàn)OutClick的示例
原始實(shí)現(xiàn)
下面是兩種常見的模態(tài)框的實(shí)現(xiàn)方式
方案一:默認(rèn) click 都是放在冒泡階段,只要在內(nèi)容區(qū)域上添加 click 的阻止冒泡即可
<div class="cover" @click="close"> <!-- 阻止冒泡 --> <div class="content" @click.stop>modal content</div> </div>
方案二:通過代碼判斷點(diǎn)擊觸發(fā)的 DOM 是否在內(nèi)容區(qū)域內(nèi)
<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) }
指令實(shí)現(xiàn)
上面的代碼可以解決全屏的模態(tài)框點(diǎn)擊外部區(qū)域關(guān)閉。但是還有一種 Pop 的彈出,這種彈出的外部區(qū)域不在本組件內(nèi),想要實(shí)現(xiàn)這種彈出的點(diǎn)擊外部區(qū)域關(guān)閉用上面的方式二也是可以的,只需把 mounted 階段把 handleClick 事件添加到 body,在 beforeDestroy 上解綁 body 上的點(diǎn)擊時(shí)間就就可以了。
如果多個(gè)組件需要實(shí)現(xiàn)這點(diǎn)擊外部區(qū)域關(guān)閉的效果,可以通過 Vue 的指令來進(jìn)行封裝
實(shí)現(xiàn)彈窗
<div class="cover"> <div class="content" v-out-click="close">modal content</div> </div>
實(shí)現(xiàn)彈出
<button @click="popIsShow = true">顯示氣泡</button> <div class="pop" v-if="popIsShow" v-out-click="closePop">I'm pop text</div>
指令代碼的具體內(nèi)容如下。有一點(diǎn)比較難受的是指令里面沒有地方能存放變量,只好把把這些變量放到了 DOM 上了。還有就是在使用的時(shí)候要加上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: 忽略點(diǎn)擊外部的按鈕初始化該組件時(shí),觸發(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) { // 通過事件捕獲的順序作為標(biāo)志位 // 最好不要使用阻止冒泡來實(shí)現(xiàn),那樣會(huì)影響其他的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指令實(shí)現(xiàn)OutClick的示例的詳細(xì)內(nèi)容,更多關(guān)于Vue指令實(shí)現(xiàn)OutClick的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue中使用event的坑及解決event is not defined
這篇文章主要介紹了Vue中使用event的坑及解決event is not defined,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03基于ant-design-vue實(shí)現(xiàn)表格操作按鈕組件
這篇文章主要為大家介紹了基于ant-design-vue實(shí)現(xiàn)表格操作按鈕組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06vue 實(shí)現(xiàn) rem 布局或vw 布局的方法
這篇文章主要介紹了vue 實(shí)現(xiàn) rem 布局的 或者 vw 布局的方法,本文給提供多種方法,需要的朋友可以參考下2019-11-11Vue實(shí)例中el和data的兩種寫法小結(jié)
這篇文章主要介紹了Vue實(shí)例中el和data的兩種寫法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-11-11