Как использовать пропсы для передачи данных дочерним компонентам в Vue 3

—

от автора

По традиции делимся полезными переводными материалами во 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>   &lt;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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *