前言
本周的状态:
Yeah! 开始开发Vue3的项目了!
No!对Vue还不太了解...
问题
项目中某功能大致描述:点击某按钮弹出选择框,之后点击其它任一地方收起选择框
emmm... 很简单嘛:
<template>
<div @click="hideActions">
<div @click.stop="toggleActions">. . .</div>
<div v-if="showActions.show">actions</div>
</div>
</template>
但!在组件外点击时却不能收起选择框,难道需要在所有外层组件捕获onClick事件并且层层传给以上组件?
当然,使用Vuex统一控制也可以,但总感觉不够优雅。
第三方库
经过google,找到了一个库 https://github.com/ndelvalle/v-click-outside
它有两种引入方式:
1、Vue.use(vClickOutside)
2、以指令方式引入
但无论哪种,都是以指令方式使用的
<div v-click-outside="onClickOutside"></div>
看起来可以解决问题了~
自定义指令
进一步了解这个库,发现是使用自定义指令(custom-directive)实现的
尝试自己造一个 v-click-outside指令
import { createApp } from 'vue'
const clickoutside = {
mounted(el, binding) {
function documentHandler(e) {
if (el.contains(e.target)) {
return false
}
if (binding.value) {
binding.value(e)
}
}
el.__vueClickOutside__ = documentHandler
document.addEventListener('click', documentHandler)
},
beforeUnmount(el) {
// 取消事件监听
document.removeEventListener('click', el.__vueClickOutside__)
delete el.__vueClickOutside__
},
}
const app = createApp(App)
app.directive('clickoutside', clickoutside)
app.mount('#app')
<template>
<div v-clickoutside="hideActions" >
<div @click.stop="toggleActions">. . .</div>
<div v-if="showActions.show">actions</div>
</div>
</template>
思考
个人感觉自定义指令和React中的高阶组件有一定的相似之处(都针对 组件/元素 进行 生命周期/参数化 相关的注入), 如何从更高的抽象角度去理解这些概念呢?
网友评论