vue.js - 将 "detect click outside"自定义指令从 Vue 2 迁移到 Vue 3

标签 vue.js vuejs3 vue-directives

基于这个问题 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);
    }
});

最佳答案

您可以像这样使用 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>

关于vue.js - 将 "detect click outside"自定义指令从 Vue 2 迁移到 Vue 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63869859/

相关文章:

node.js - 如何自动刷新日志而不是手动刷新

javascript - 停止检查 alpineJS 中的复选框?

vue.js - 如何修复 Vue 3 模板编译错误 : v-model value must be a valid JavaScript member expression?

javascript - 如何在 v-for 循环中使用 BootstrapVue - Modal?

vue.js - 更改 Vuejs 中的 v-model 输入值时,数据不会动态更新

javascript - VueJS : Re-create component after clicking on the same "router-link"?

javascript - 如何让IDEA支持Vue.js标签属性

javascript - 在 Vue3 中定义和重用内联组件

typescript - 如何在 Vue 中扩充 `ElementAttrs<HTMLAttributes>` 界面?

vue.js - v-for 与 v-if 处于同一级别,影响 v-else