美文网首页
记遇到的第一个Vue相关问题:自定义指令

记遇到的第一个Vue相关问题:自定义指令

作者: 隐号骑士 | 来源:发表于2021-03-07 10:45 被阅读0次

    前言

    本周的状态:

    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)实现的

    • 关于自定义指令,可以看官方文档 Vue2 / Vue3,两个版本的差别主要在钩子函数

    尝试自己造一个 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中的高阶组件有一定的相似之处(都针对 组件/元素 进行 生命周期/参数化 相关的注入), 如何从更高的抽象角度去理解这些概念呢?

    相关文章

      网友评论

          本文标题:记遇到的第一个Vue相关问题:自定义指令

          本文链接:https://www.haomeiwen.com/subject/xbieqltx.html