vue.js - vue 3指令监听vue发出

标签 vue.js vuejs3

我想要实现的是构建一个加载vue指令,
带有 v-loading 指令的函数将渲染微调器并阻止事件,直到函数 promise 解析或拒绝。

到目前为止我尝试过的:

  1. 使用addEventListener,但只能监听dom的原生事件,不能监听vue事件
  2. 劫持 vue $emit 函数,但收到警告说不要覆盖名为 $ 的 vue 原生函数,即使这个解决方案有效,我认为这是一个糟糕的解决方案。
  3. 在指令参数中,绑定(bind).实例[绑定(bind).值.名称]引用组件中的onEvent函数,我尝试覆盖它但它不起作用。当 onEvent 再次触发时,它会运行覆盖之前的旧 onEvent。
  4. 第三方事件发射器(例如,mitt)。这种方法效果很好,但是自定义组件必须编写额外的代码来发出事件。
    如下面的示例代码,
    v-loading的用户必须记住写2个emit(mitt和vue的emit)。
    它并不是那么简单,而且它有额外的依赖性。
// mitt solution
// custom-component template
<custom-component v-loading:event="onEvent">
// custom-component script
setup(props, {emit}) {
  function emitEvent() {
    emit("event");
    // bad: have to remember to write this extra line, and it is third party dependency
    mittEmitter.emit("event");
  }
}

那么,还有其他解决方案可以从 vue 的 $emit 监听 vue 的事件(不是 dom 的 native 事件)吗?


LoadingDirective.ts

import { Directive } from "vue";

const Loading: Directive = {
  mounted(el, binding) {
    const eventName = binding.arg;
    const onEvent = binding.value;
    // I want to listen vue's event(eventName) here
    // do something extra
    onEvent();  // original onEvent() function to run in App.vue
    // do something extra
  }
};
export default Loading;

App.vue

<template>
  <!-- when onEvent triggered, a spinner will be render in custom-component -->
  <custom-component v-loading:event="onEvent" />
</template>

CustomComponent.vue

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  setup(props, {emit}) {
    function emitEvent() {
      // use only vue's emit
      emit("event")
    }
    return {
      onEvent
    };
  }
});
</script>

最佳答案

Vue 3 文档 recommends使用外部库,例如 mitttiny-emitter

JSFiddle Example

<template>
    <div id="app">
        <custom-component v-loading="eventHandler" />
    </div>
</template>
const emitter = mitt();

const customComponent = { template: '<h1>Example</h1>' };

const app = Vue.createApp({
    components: { customComponent },

    setup() {
        setTimeout(() => {
            emitter.emit('loadingEvent', { colour: 'Green' });
        }, 1000);
        
        const eventHandler = e => console.log('Handled!', e);
        
        return { eventHandler };
    },
});

app.directive('loading', {
    mounted(el, binding) {
        const func = binding.value;

        emitter.on('loadingEvent', data => {
            // your logic here...
            func(data);
        });
    },
});

app.mount('#app');

关于vue.js - vue 3指令监听vue发出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64441717/

相关文章:

由于不安全评估,Vue.js 3 扩展在使用 "vue-cli-service build"时中断

javascript - 未捕获( promise )TypeError : Cannot set property 'playerName' of undefined at eval

typescript - 在 Pixijs 中加载 spritesheet 不起作用

javascript - 使用 VueJS 过滤复选框

vue.js - Vue.component 不是一个函数/从 Vue 2 迁移到 Vue 3 版本

vue.js - 我怎么能在组合 api 中观看 Prop ?

javascript - 为什么通过 Vue-router 传递数据返回 "[object Object]"?

javascript - Vue.js - onclick 事件不触发

vue.js - 为什么Webstorm的Vue插件应用后不起作用?

vue.js - 在 Vue3 中使用过滤器但无法读取 globalProperties