#vue.js #vue-component
#vue.js #vue-компонент
Вопрос:
Я прочитал о передаче переменных от дочернего к родительскому, используя $emit
, но я пока не могу полностью понять это.
В App.vue у меня есть <header/>
компонент для заголовка страницы, содержащий кнопку, которая управляет видимостью мобильной навигации. При нажатии он меняет свой класс:
<button @click="toggleMobileNavigation" :class="isOpen ? 'is-open' : 'is-closed'">
Это <header/>
js:
export default {
data() {
return {
isOpen: false,
};
},
methods: {
toggleMobileNavigation() {
if(!this.isOpen) {
this.isOpen = true;
} else {
this.isOpen = false;
}
this.$emit(this.isOpen)
}
}
}
App.vue:
<Header />
<main id="main" tabindex="-1" class="main" :class="isOpen">
Очевидно, что это не работает, и я не могу понять, как правильно перехватить $emit
.
Спасибо за любые советы!
Комментарии:
1. используйте vuex, или сделайте заголовок плагином, у которого есть своя собственная шина событий, или передайте глобальную
:state="state"
опору, вокруг которой есть header.isOpen prop, или добавьте ссылку в заголовок и получите доступ через this.$refs.header, или глобальную шину событий, или перейдите отthis
$root затем в заголовоккомпонент, есть несколько способов
Ответ №1:
Я бы сказал, что вы на правильном пути, этот дочерний элемент должен выдать какое-то событие, чтобы предупредить своего родителя о важном изменении.
Но вместо того, чтобы делать это в вашем компоненте заголовка:
this.$emit(this.isOpen)
Укажите имя события:
this.$emit('opened', this.isOpen)
// or:
if (this.isOpen) {
this.$emit('opened');
} else {
this.$emit('closed');
}
Способ, которым вы перехватываете это событие в родительском компоненте (App.vue), должен быть:
<Header @opened="handleOpenedEvent"> // will call method handleOpenedEvent
// alternatively:
<Header @opened="menuStatus = $event"> // $event contains data you supply as second argument to your this.$emit(name, ...) call
// @[eventname] is one way of doing it, v-on is the same:
<Header v-on:opened="handleEvent">
Комментарии:
1. Привет! Спасибо за ваш ответ, он вывел меня на правильный путь. Каким-то образом я также должен установить
emits: ["sendnavigationstatus"]
export default
внутри дочернего шаблона. В любом случае, спасибо Джошуа и счастливого нового года!2. Привет, Анна, я не знал, что это (свойство emits) необходимо, я пытался найти это в документах Vue, но не смог его найти. Не могли бы вы указать мне правильное направление? И вас с новым годом.
3. Спасибо, кое-что узнал! Я работал с Vue 2, поэтому я пропустил это!
4. У вас есть эта локальная переменная (пусть isOpen), о существовании которой Vue не знает. Я бы добавил isOpen в функцию данных, в navigationStatus() заменил локальную переменную isOpen на this.isOpen . Это должно сработать, по крайней мере, в Vue 2, я знаю, что так и будет ;-). Если вы используете Vue3 composition api с этими типами ссылок, возможно, посмотрите здесь: v3.vuejs.org/guide/composition-api-introduction.html
5. Еще одна вещь, которую следует отметить в отношении имен динамических классов, вы используете ее следующим образом:
:class='{someClass: isOpen}'
или:class=" 'dynamic-string' (isOpen ? 'opened' : '')"'