#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 есть шанс на успех.