Vue3: проверьте, привязан ли прослушиватель событий к экземпляру компонента

#vue.js

#vue.js #vuejs3

Вопрос:

У меня есть многоразовый компонент значка. Я хочу иметь возможность добавлять кнопку закрытия / удаления, когда в экземпляре компонента присутствует прослушиватель событий OnDelete.

 <template>
    <div class="flex inline-flex items-center px-2.5 py-0.5 text-xs font-medium select-none" :class="[square ? '' : 'rounded-full']">
        <slot />
        <button class="cursor-pointer ml-2" @click="$emit('onDelete')">
            <XIcon class="flex-shrink-0 h-3.5 w-3.5 text-gray-400 hover:text-gray-500" aria-hidden="true" />
        </button>
    </div>
</template>

<script>
    import { XIcon } from '@heroicons/vue/solid';

    export default {
        props: {
            color: { type: String },
            square: { type: Boolean, default: false },
        },
        components: {
            XIcon,
        },
        emits: ['onDelete'],
    };
</script>
 

Если я добавлю оператор v-if к кнопке, событие emit будет выполнено немедленно

 <button v-if="$emit('onDelete')" class="cursor-pointer ml-2" @click="$emit('onDelete')">
 

Я использую Vue 3

Комментарии:

1. Как onDelete emit is passed by the parent component ? в этом случае только color и square передаются родительским

2. @Radeanu <Badge square @onDelete="onDeleteOption(selected_option)">Test</Badge>

3. Извините, вы можете проверить, существует ли onDelete прослушиватель таким образом v-if="$listeners.onDelete"

4. Но в Vue 3 $listeners был удален

5. Для Vue 3 используйте v-if="$attrs.onOnDelete"

Ответ №1:

ОБНОВЛЕНИЕ: если ваш компонент использует новую опцию emits в Vue3, что является рекомендуемой наилучшей практикой из документов Vue3, прослушиватели событий не будут отделены от $attrs . Проблема будет передана команде Vue для получения разъяснений и указаний о том, почему это ведет себя таким образом.


Я упростил ваш пример выше в StackBlitz, чтобы изолировать нужную вам функциональность.

Важное замечание, я использую Vue 3.2.26.

В Vue3 были удалены прослушиватели $.

Прослушиватели событий теперь являются частью $attrs . Однако при простом входе this.$attrs в консоль Badge не будет отображаться искомый ключ, они находятся внутри targets , но доступны путем добавления on к имени связанного события. В вашем случае в Badge компоненте, который вы будете использовать onOnDelete .

введите описание изображения здесь

Завершите рабочий пример двумя значками. Один будет отображаться, потому что у него есть связанное событие onDelete , другой не будет из-за того, что привязка onDelete отсутствует.

https://stackblitz.com/edit/vue-8b6exq?devtoolsheight=33amp;file=src/components/Badge.vue

Комментарии:

1. Пример работает, но он не работал в моем проекте. Проблема emits: ['onDelete'] в тегах скрипта. При добавлении v-if="$attrs.onOnDelete" не работает. Без него это работает

2. @Thore очень интересно. Я только что проверил это. Возможно, вы захотите сообщить об этой проблеме команде Vue

3. @MaxvandeLaar Я не верю, что он был отправлен, и здесь объясняется, почему v3.vuejs.org/api/options-data.html#emits и здесь v3.vuejs.org/guide/component-attrs.html#attribute-inheritance

4. Теперь я добавлю запрос функции

5. @TimWickstrom Спасибо! Предложенный обходной путь кажется мне неправильным. Я надеюсь, что у RFC есть шанс на успех.