【问题标题】:Migrating "detect click outside" custom directive from Vue 2 to Vue 3将“检测外部点击”自定义指令从 Vue 2 迁移到 Vue 3
【发布时间】:2020-12-31 07:44:49
【问题描述】:

基于这个问题Detect click outside element 和这个答案https://stackoverflow.com/a/42389266,我正在尝试将指令从Vue 2 迁移到Vue 3。似乎binding.expressionvnode.context 不存在更多。我怎样才能让它发挥作用?

app.directive('click-outside', {
    beforeMount (el, binding, vnode) {
        el.clickOutsideEvent = function (event) {
            if (!(el === event.target || el.contains(event.target))) {
                vnode.context[binding.expression](event);
            }
        };
        document.body.addEventListener('click', el.clickOutsideEvent);
    },
    unmounted (el) {
        document.body.removeEventListener('click', el.clickOutsideEvent);
    }
});

【问题讨论】:

  • 我不知道您的具体用例,但是很多时候人们想要在事件之外使用点击,他们没有考虑到可访问性,因为只有键盘的用户可能需要相同的功能才能发生当外部发生模糊事件或“焦点”时。如果您不想重新发明轮子并且可以添加另一个库,这是我过去使用的一个很棒的库,用于实现外部点击和外部模糊。 npmjs.com/package/vue-outside-events
  • @maxshuty 感谢您的建议,但显示的库适用于 vue 2

标签: vue.js vuejs3 vue-directives


【解决方案1】:

您可以像这样使用binding.value

const { createApp } = Vue;

const highlightEl = (color ) => (event, el) => {
  if (el) {
    el.style.background = color;
  } else {
    event.target.style.background = color;
  }
}
const clearHighlightEl = (event, el) => {
  if (el) {
    el.style.background = '';
  } else {
    event.target.style.background = '';
  }
}

const app = Vue.createApp({
  setup() {
    return {
      highlightEl,
      clearHighlightEl
    }
  }
})

app.directive('click-outside', {
  beforeMount(el, binding, vnode) {
    el.clickOutsideEvent = function(event) {
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event, el);
      }
    };
    document.body.addEventListener('click', el.clickOutsideEvent);
  },
  unmounted(el) {
    document.body.removeEventListener('click', el.clickOutsideEvent);
  }
});

app.mount('#app')
<script src="https://unpkg.com/vue@3.0.0-rc.11/dist/vue.global.prod.js"></script>

<div id="app">
  <h1 v-click-outside="highlightEl('yellow')" @click="clearHighlightEl">Element 1</h1>
  <p v-click-outside="highlightEl('#FFCC77')" @click="clearHighlightEl">Element 2</p>
</div>

【讨论】:

    【解决方案2】:

    在上下文之外,在 vue3 中有一个更简单的方法与组合。

    Link to Vueuse ClickOutside

    <template>
      <div ref="target">
        Hello world
      </div>
      <div>
        Outside element
      </div>
    </template>
    
    <script>
    import { ref } from 'vue'
    import { onClickOutside } from '@vueuse/core'
    
    export default {
      setup() {
        const target = ref(null)
    
        onClickOutside(target, (event) => console.log(event))
    
        return { target }
      }
    }
    </script>
    

    【讨论】:

    • 这是真正的 vue3 解决方案
    • @MojtabaHn 我确认了
    猜你喜欢
    • 2020-12-24
    • 2021-03-13
    • 2021-09-11
    • 2017-12-23
    • 2021-06-20
    • 2018-10-20
    • 2020-08-27
    • 2019-11-06
    • 2017-11-06
    相关资源
    最近更新 更多