По традиции делимся полезными переводными материалами во frontend-разработке. В этот раз frontend-специалист SimbirSoft Никита сделал выбор в пользу материалов Nwose Lotanna, опубликованных на сайте blog.logrocket.com. С разрешения автора мы перевели статью, в которой он рассказывать о способах использования пропсов для передачи данных дочерним компонентам в Vue 3.
Примечание автора: Данная статья последний раз была обновлена 15 декабря 2022, чтобы отразить обновления, добавленные в Vue 3.
Пропсы — это важная фича в Vue для управления родительскими и дочерними компонентами, однако взаимодействие с ними может быть довольно мудреным. В этой статье мы изучим, как передавать данные из родительского компонента в дочерний с использованием пропсов в Vue 3. Весь код из этой статьи вы можете найти на GitHub. Что ж, начнем!

Содержание:
-
Перед началом
-
Что такое пропсы в Vue?
-
Зачем мне использовать пропсы?
-
Определение данных в родительском компоненте
-
Получение пропсов в Vue
-
Регистрация пропсов в Vue
-
Использование пропсов в Vue
-
Строго типизированные пропсы
Перед началом
Эта статья предназначена для разработчиков любого уровня, включая новичков.
Чтобы отслеживать то, что будет происходить в этой статье, вам понадобится установленный Node.js версии не ниже 16.х. Вы можете проверить установленную версию в терминале, выполнив команду:
node -v
Кроме того, вам понадобится текстовый редактор. Мы настоятельно рекомендуем VS Code. И наконец, вам необходим глобально установленный Vue 3. На момент написания статьи, актуальной является третья версия.
Прежде чем начать, скачайте стартовый проект Vue. Разархивируйте скачанный проект, перейдите в папку проекта, а затем выполните команду ниже для установки всех зависимостей:
npm install
Что такое пропсы в Vue?
Пропс в Vue — это кастомный атрибут, который вы можете зарегистрировать в любом компоненте. Вы определяете данные в родительском компоненте и присваиваете им определенное значение. Затем переходите в дочерний компонент, которому эти данные необходимы, и передаете значение атрибуту props. В результате данные становятся свойством дочернего компонента.
В компоненте, реализованном на Composition API, то есть с использованием <script setup>, синтаксис будет выглядеть следующим образом:
<script setup> const props = defineProps(['title']) console.log(props.title) </script>
Для компонентов, реализованных с помощью Options API:
export default { props: ['title'], setup(props) { // setup() принимает пропсы в качестве первого аргумента console.log(props.title) } }
Чтобы получить доступ к этим данным динамически из любого компонента, которому они нужны, вы можете использовать корневой компонент App.vue как родительский, хранить в нем данные, а затем регистрировать пропсы.
Зачем мне использовать пропсы?
Давайте представим, что у вас в есть объект с данными, которые вы хотите по-разному отобразить в двух разных компонентах. К примеру, пусть это будет топ-10 лучших исполнителей. Вполне вероятно, что в первую очередь вы подумаете о создании двух отдельных компонентов, в каждом из которых будет массив объектов с исполнителями и их отображение с помощью блока <template>.
В данном случае это будет отличным решением, однако по мере масштабирования проекта и добавления все новых и новых компонентов, этот метод перестанет быть эффективным. Давайте убедимся в этом на примере стартового проекта, который вам нужно открыть с помощью VS Code. Откройте файл 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', data (){ return { artists: [ {name: 'Davido', genre: 'afrobeats', country: 'Nigeria'}, {name: 'Burna Boy', genre: 'afrobeats', country: 'Nigeria'}, {name: 'AKA', genre: 'hiphop', country: 'South-Africa'}, {name: 'Sarkodie', genre: 'hiphop', country: 'Ghana'}, {name: 'Stormzy', genre: 'hiphop', country: 'United Kingdom'}, {name: 'Lil Nas', genre: 'Country', country: 'United States'}, {name: 'Nasty C', genre: 'hiphop', country: 'South-Africa'}, {name: 'Shatta-walle', genre: 'Reagae', country: 'Ghana'}, {name: 'Khalid', genre: 'pop', country: 'United States'}, {name: 'ed-Sheeran', genre: 'pop', country: 'United Kingdom'} ] } } } </script>
Создайте новый файл Test2.vue в папке Components и скопируйте в него код ниже:
<template> <div> <h1>Vue Top Artist Countries</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', data (){ return { artists: [ {name: 'Davido', genre: 'afrobeats', country: 'Nigeria'}, {name: 'Burna Boy', genre: 'afrobeats', country: 'Nigeria'}, {name: 'AKA', genre: 'hiphop', country: 'South-Africa'}, {name: 'Sarkodie', genre: 'hiphop', country: 'Ghana'}, {name: 'Stormzy', genre: 'hiphop', country: 'United Kingdom'}, {name: 'Lil Nas', genre: 'Country', country: 'United States'}, {name: 'Nasty C', genre: 'hiphop', country: 'South-Africa'}, {name: 'Shatta-walle', genre: 'Reagae', country: 'Ghana'}, {name: 'Khalid', genre: 'pop', country: 'United States'}, {name: 'ed-Sheeran', genre: 'pop', country: 'United Kingdom'} ] } } } </script> <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>
Чтобы зарегистрировать новый компонент, который вы только что создали, откройте файл App.vue и скопируйте в него код:
<template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png"> <Test/> <Test2/> </div> </template> <script> import Test from './components/Test.vue' import Test2 from './components/Test2.vue' export default { name: 'app', components: { Test, Test2 } } </script>
В терминале VS Code запустите ваш проект локально, выполнив команду:
npm run dev
Результат в окне браузера должен быть следующим:

Вы заметите, что если вам понадобится создать еще 5 похожих компонентов, вы будете копировать данные в каждый компонент по отдельности. Однако существует возможность один раз объявить данные в родительском компоненте, а затем передавать их в каждый из дочерних компонентов с помощью пропсов.
Определение данных в родительском компоненте
В тот момент, когда вы выбрали корневой компонент в качестве родительского, вам в первую очередь необходимо определить объект с данными внутри него. Если вы продолжаете следить за тем, что мы делаем, откройте файл App.vue и скопируйте объект с данными в секцию <script>.
<template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png" /> <Test /> <Test2 /> </div> </template> <script> import Test from "./components/Test.vue"; import Test2 from "./components/Test2.vue"; 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" }, { name: "Sarkodie", genre: "hiphop", country: "Ghana" }, { name: "Stormzy", genre: "hiphop", country: "United Kingdom" }, { name: "Lil Nas", genre: "Country", country: "United States" }, { name: "Nasty C", genre: "hiphop", country: "South-Africa" }, { name: "Shatta-walle", genre: "Reagae", country: "Ghana" }, { name: "Khalid", genre: "pop", country: "United States" }, { name: "Ed Sheeran", genre: "pop", country: "United Kingdom" }, ], }; }, }; </script>
Получение пропсов в Vue
После определения данных, перейдите в каждый из дочерних компонентов и удалите из них объекты data() вместе с их содержимым. Чтобы прокинуть пропсы в компонент, вы должны объявить пропсы, которые хотите получить, внутри каждого из компонентов. В каждом из Test-компонентов на месте объектов с данными, которые мы только что удалили, создайте новое свойство так, как показано ниже:
<script> export default { name: 'Test', props: ['artists'] } </script>
Регистрация пропсов в Vue
Чтобы дать движку Vue понять, что у вас есть пропсы, которые вы динамически хотите передать в дочерние компоненты, вы должны сигнализировать об этом внутри родительского компонента. Сделать это можно в секции <template>, как показано ниже:
<template> <div id="app"> <Test v-bind:artists="artists"/> <Test2 v-bind:artists="artists" /> </div> </template>
<script> export default { name: 'Test', props: { artists: { type: Array } } } </script>
В коде выше мы используем директиву v-bind, чтобы связать массив artists в родительском компоненте с пропсом artists, который находится в каждом из дочерних компонентов.
Если вы сделаете это без использования директивы, то никакого смысла в этом не будет. Будьте внимательны: ни компилятор Vue, ни ESLint не подсветят это как ошибку:
<Test artists="artists"/> <Test2 artists="artists"/>
Поэтому так важно быть внимательным и помнить об использовании директивы v-bind для всех динамических связок.
Использование пропсов в Vue
После того как вы настроили пропсы в своем проекте Vue, вы можете использовать их внутри дочерних компонентов так, будто данные были объявлены внутри каждого из них. Это значит, что доступ к данным будет осуществляться с помощью this.artists.
Строго типизированные пропсы
При строгой типизации пропсов вы можете быть уверены, что дочерний компонент получит именно тот тип данных, который вам нужен. В стартовом проекте для созданных нами пропсов вы можете добавить условие, что в качестве пропсов могут быть переданы только массивы:
<script> export default { name: 'Test', props: { artists: { type: Array } } } </script>
Как следствие, если вы попытаетесь передать пропсом неверный тип, например String, то в консоли появится сообщение об ошибке, которая укажет на несоответствие типов:

Заключение
В этой статье мы открыли для себя пропсы в Vue 3, выяснили, как они могут помочь соблюдать принцип DRY (не повторяйся) путем переиспользования объектов с данными. Мы также выяснили, как регистрировать и передавать пропсы внутри проекта Vue. Более подробную информацию о пропсах можно найти в официальной документации Vue. Удачи!
Спасибо за внимание! Надеемся, что этот перевод был полезен для вас.
Авторские материалы для разработчиков мы также публикуем в наших соцсетях – ВК и Telegram.
ссылка на оригинал статьи https://habr.com/ru/articles/725506/
Добавить комментарий