От автора: в этом посте мы рассмотрим, как во Vue.js данные и их состояние могут передаваться из дочернего компонента в его родительский компонент с помощью emit — эмиттеров событий.
Прежде чем вы начнете…
Этот пост подходит для разработчиков всех уровней, включая начинающих. Вот несколько вещей, которые вы должны уже иметь, прежде чем читать эту статью:
Установленный Node.js версии 10.x и выше. Вы можете проверить это, выполнив в терминале / командной строке команду, приведенную ниже:
node -v
Редактор кода — я настоятельно рекомендую Visual Studio Code
Последнюю версию Vue, установленную на вашем компьютере
Vue CLI 3.0. Для этого сначала удалите старую версию CLI:
npm uninstall -g vue-cli
Затем установите новую:
npm install -g @vue/cli
Скачать стартовый проект Vue можно здесь
Распакуйте загруженный проект
Перейдите в разархивированный файл и выполните приведенную ниже команду, чтобы обновить все зависимости:
npm install
Передача данных через компоненты
Чтобы передать значения данных из родительских компонентов (например, app.vue) в дочерние (например, вложенные компоненты) внутри компонента приложения, Vue.js предоставляет нам платформу, называемую props. Props можно назвать пользовательскими атрибутами, которые можно зарегистрировать в компоненте, что позволяет определять данные в родительском компоненте, присваивать ему значение, а затем передавать значение в атрибут prop, на который затем можно ссылаться в дочерних компонентах.
В этом посте мы покажем обратный процесс. Чтобы передать и обновить значения данных в родительском компоненте из дочернего компонента таким образом, чтобы все остальные вложенные компоненты также были обновлены, мы используем конструкцию emit для обработки запуска событий и обновления данных.
Демонстрация
Мы рассмотрим процесс отправки событий из дочернего компонента, настроим прослушивание родительского компонента для передачи данных из дочернего компонента и, наконец, обновим значение данных.
Если вы следовали этому руководству с самого начала, вы скачали и открыли стартовый проект в VS Code. Проект является законченным, полным кодом к этому посту.
Причина, по которой этот проект является стартовым, заключается в том, что вы можете поэкспериментировать с концепцией prop, прежде чем начать знакомство с процессом.
Приступая к работе
В папке вы найдете два дочерних компонента: test.vue и test2.vue и родительский компонент, являющимся файлом app.vue. Мы будем использовать заголовки двух дочерних компонентов, чтобы проиллюстрировать этот подход. Ваш файл Test.vue должен выглядеть так:
<template> <div> <h1>Vue Top 20 Artists</h1> <ul> <li v-for="(artist, x) in artists" :key="x"> <h3>{{artist.name}}</h3> </li> </ul> </div> </template> <script> export default { name: 'Test', props: { artists: { type: Array } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> li{ height: 40px; width: 100%; padding: 15px; border: 1px solid saddlebrown; display: flex; justify-content: center; align-items: center; } a { color: #42b983; } </style>
Чтобы хедер получил заголовок из неявного определения в разделе свойств данных, вы создаете раздел данных и добавляете определение, а затем добавляете в шаблон символ интерполяции, например:
<template> <div> <h1>{{header}}</h1> <ul> <li v-for="(artist, x) in artists" :key="x"> <h3>{{artist.name}}</h3> </li> </ul> </div> </template> <script> export default { name: 'Test', props: { artists: { type: Array } }, data() { return { header: 'Vue Top Artists' } } } </script>
Если вы запустите приложение, то получите точно такой же интерфейс, который получили в самом начале. Следующим шагом является изменение этого определенного свойства при нажатии.
Переключение заголовка
Чтобы переключить заголовок, вам нужно будет добавить к хедеру прослушиватель событий клика и указать функцию, содержащую логику, которая должна выполняться при нажатии.
<template> <div> <h1 v-on:click="callingFunction">{{header}}</h1> <ul> <li v-for="(artist, x) in artists" :key="x"> <h3>{{artist.name}}</h3> </li> </ul> </div> </template> <script> export default { name: 'Test', props: { artists: { type: Array } }, data() { return { header: 'Vue Top Artists' } }, methods: { callingFunction(){ this.header = "You clicked on header 1"; } } } </script>
Теперь ваш хедер меняется на строку внутри вызывающей функции при нажатии.
Установка эмиттера
На этом этапе нам нужно передать такое же поведение родительскому компоненту, чтобы при клике каждый заголовок, вложенный в родительский компонент, изменялся.
Для этого мы создадим эмиттер, который будет генерировать событие в дочернем компоненте, которое родительский компонент может прослушивать и реагировать на него (это то же самое, что и логика прослушивателя событий для компонентов).
Измените раздел script в файле Test.vue на блок кода ниже:
<script> export default { name: 'Test', props: { artists: { type: Array }, header: { type: String } }, data() { return { // header: 'Vue Top Artists' } }, methods: { callingFunction(){ // this.header = "You clicked on header 1" this.$emit('toggle', 'You clicked header 1'); } } } </script>
Здесь тип ожидаемых данных заголовка был определен как prop. Затем в методе есть оператор emit, который указывает Vue запускать событие (точно так же, как любое другое — например, событие клика) при переключении и передавать строку в качестве аргумента. Это все, что вам нужно для настройки события, которое будет прослушиваться внутри другого компонента.
Прослушивание запущенного события
Теперь следующее, что нужно сделать после создания события — это прослушать и ответить на него. Скопируйте этот блок кода в файл app.vue:
<template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png"> <Test v-bind:header="header" v-on:toggle="toggleHeader($event)" /> <Test v-bind:artists="artists" /> <test2 v-bind:header="header"/> <test2 v-bind:artists="artists" /> </div> </template> <script> import Test from './components/Test.vue' import Test2 from './components/Test2' export default { name: 'app', components: { Test, Test2 }, data (){ return { artists: [ {name: 'Davido', genre: 'afrobeats', country: 'Nigeria'}, {name: 'Burna Boy', genre: 'afrobeats', country: 'Nigeria'}, {name: 'AKA', genre: 'hiphop', country: 'South-Africa'} ], header: 'Vue Top Artists' } }, methods: { toggleHeader(x){ this.header = x; } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
В разделе template вы можете видеть, что первый компонент Test имеет две директивы Vue. Первая — это v-bind, которая связывает начальное свойство заголовка с неявным определением в объекте данных в массиве Artist; при инициализации отображается строка Vue Top Artists.
Вторая директива — это v-on для прослушивания событий; прослушиваемое событие — это переключение (помните, вы уже определили его в компоненте Test), а вызывающая функция для него — toggleHeader. Эта функция создана, и строка из дочернего компонента передается через аргумент $event для отображения здесь.
Суть
Эта реализация передает данные через эмиттер в родительский компонент, и поэтому, поскольку другие компоненты вложены в родительский компонент, данные в каждом из вложенных компонентов повторно визуализируются и обновляются. Перейдите к файлу test2.vue и скопируйте в него этот блок кода:
<template> <div> <h1>{{header}}</h1> <ul> <li v-for="(artist, x) in artists" :key="x"> <h3>{{artist.name}} from {{artist.country}}</h3> </li> </ul> </div> </template> <script> export default { name: 'Test2', props: { artists: { type: Array }, header: { type: String } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped> li{ height: 40px; width: 100%; padding: 15px; border: 1px solid saddlebrown; display: flex; justify-content: center; align-items: center; } a { color: #42b983; } </style>
Здесь была установлена интерполяция данных и указана как строка в объекте props. Запустите приложение на своем сервере разработки:
npm run serve
Вы видите, что после того, как событие было обработано в родительском компоненте, во всех компонентах обновился заголовок, даже если определение было указано только в одном дочернем компоненте. Вы можете найти полный код этого руководства здесь, на GitHub.
Заключение
Вы можете увидеть еще одну интересную сторону использования во Vue событий с помощью эмиттеров: теперь вы можете создать событие в одном компоненте и прослушивать, а также реагировать на него в другом компоненте. Это может иметь много вариантов использования, которые будут действительно полезны в вашем рабочем процессе — счастливого кодирования!
Автор: Nwose Lotanna
Источник: https://blog.logrocket.com
Редакция: Команда webformyself.