将“检测外部点击”自定义指令从 Vue 2 迁移到 Vue 3

Sau*_*ron 4 vue.js vue-directives vuejs3

基于这个问题检测点击外界因素而这个答案/sf/answers/2967248651/,我想该指令从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);
    }
});
Run Code Online (Sandbox Code Playgroud)

Dan*_*iel 8

你可以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')
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)


Min*_*mai 5

脱离上下文,在 vue3 中有一种更简单的组合方式。

链接到 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>
Run Code Online (Sandbox Code Playgroud)

  • 这是真正的vue3解决方案 (3认同)