Vue 3 директивы listen vue emit


Vue 3 директивы listen vue emit

20.10.2020 11:53:58 Просмотров 34 Источник

Чего я хочу добиться, так это построить директивы загрузки vue,
функция с директивой v-loading будет отображать spinner и блокировать событие до тех пор, пока функция не разрешит или не отклонит обещание.

То, что я пробовал до сих пор:

  1. используйте addEventListener, но он может прослушивать только собственное событие dom, а не событие vue
  2. hijack vue $emit function, но получите предупреждение, что не переопределяйте собственную функцию vue с именем $, даже если это решение работает, я думаю, что это плохое решение.
  3. в аргументе директив binding. instance[binding.value.name] обратитесь к функции onEvent в компоненте, я попытался переопределить ее, но она не работает. Когда onEvent срабатывает снова,он запускает старый onEvent перед переопределением.
  4. сторонний излучатель событий (например, mitt). этот метод работает хорошо, но пользовательскому компоненту приходится писать дополнительный код для генерации события.
    Как пример кода ниже,
    пользователь в-Нагрузки должны помнить, чтобы написать 2 испускать (испустить рукавицей и по Вью).
    Это не так прямолинейно, и у него есть дополнительная зависимость.
// 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(а не родного события dom) из $emit vue?


LoadingDirective.ТС

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;

Приложение.Вью

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

CustomComponent.Вью

<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 директивы listen vue emit / vue 3 directives listen vue emit

Является ответом!
Matt Deacalion

25.10.2020 12:55:28

Документация Vue 3 рекомендует использовать внешнюю библиотеку, такую как mitt или tiny-emitter.

Пример JSFiddle

<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');
Помочь в развитии проекта:
Закрыть X