Что такое props vue
Каждый компонент может определять параметр props , через который в компонент можно передать извне различные данные. Например:
Компоненты Vue 3
Параметр props хранит массив ключей или свойств, которым извне можно передать значения. В данном случае определено одно свойство message. Это свойство также можно использовать в шаблоне компонента ( > ).
Чтобы передать свойству значение, у элемента компонента применяется атрибут, который называется также, как и свойство:
В некотором плане свойства props похожи на те свойства, которые определяются через параметр data. В принципе мы даже могли бы определить свойство с одним и тем же именем и в props, и в data:
app.component('message-comp', < props: ['message'], data()< return < message: 'hi all'>>, template: '>
' >)
И в данном случае Vue 3 использовало свойство message из data, а не из параметра props, тем не менее в консоли мы бы увидели предупреждение, что свойство тем же именем также определено и в параметре props. Поэтому такой двойственности лучше избегать.
Динамические свойства
В примере выше свойству message передается статическое литеральное значение — строка «hello». Однако можно также устанавливать значения свойств динамически в зависимости от введенных в поля ввода данных:
Компоненты Vue 3
Теперь свойство message устанавливается динамически в зависимости от введеного значения:
Для этого применяется механизм привязки — перед атрибутом указывается директива v-bind, которая определяет, к какому значению идет привязка:
Также можно использовать сокращенную форму:
Привязка к сложным объектам
Допустим, наш компонент выводит данные о пользователе — имя и возраст. Передадим эти данные в компонент:
Компоненты Vue 3
Здесь компонент получает значения для своих свойств name и age.
Но в данном случае свойства name и age можно оформить как единый объект и передавать этот объект целиком в компонент:
С помощью атрибута v-bind=»user» объект user сразу передается компоненту и автоматически сопоставляется со свойствами name и age, которые определены в компоненте. Но естественно должно быть соответствие между названиями свойств объекта user и названиями свойств компонента. В остальном результат работы будет тот же самый, что и в предыдущем случае. В то же время несмотря на то, что вроде бы идет привязка к объекту user, тем не менее компонент получает значения его свойств по отдельности.
Что такое props vue
Каждый компонент определяет параметр props , через который мы можем передать компоненту извне различные данные. Например:
Компоненты Vue.js
Параметр props хранит массив ключей или свойств, которым извне можно передать значения. В данном случае определено одно свойство message. Это свойство также можно использовать в шаблоне компонента ( > ).
Чтобы передать свойству значение, у элемента компонента применяется атрибут, который называется также, как и свойство:
В некотором плане свойства props похожи на те свойства, которые определяются через параметр data. При этом надо учитывать, что мы не можем определить свойство с одним и тем же именем и в props, и в data:
Vue.component('message-comp', < props: ['message'], data: function()< return < message: 'hi all'>>, template: '>
' >)
И в данном случае будет использоваться свойство message из props, а не из параметра data.
Динамические свойства
В примере выше свойству message передается статическое литеральное значение — строка «hello». Однако можно также устанавливать значения свойств динамически в зависимости от введенных в поля ввода данных:
Компоненты Vue.js
Теперь свойство message устанавливается динамически в зависимости от введеного значения:
Для этого применяется механизм привязки — перед атрибутом указывается директива v-bind, которая определяет, к какому значению идет привязка:
Также можно использовать сокращенную форму:
Привязка к сложным объектам
Допустим, наш компонент выводит данные о пользователе — имя и возраст. Передадим эти данные в компонент:
Компоненты Vue.js
Age: >
' >) new Vue( < el: "#app", data: < name: '', age: 18 >>);
Здесь компонент получает значения для своих свойств name и age.
Но в данном случае свойства name и age можно оформить как единый объект и передавать этот объект целиком в компонент:
Age: >
' >) new Vue( < el: "#app", data: < user: < name: '', age: 18 >> >);
С помощью атрибута v-bind=»user» объект user сразу передается компоненту и автоматически сопоставляется со свойствами name и age, которые определены в компоненте. Но естественно должно быть соответствие между названиями свойств объекта user и названиями свойств компонента. В остальном результат работы будет тот же самый, что и в предыдущем случае. В то же время несмотря на то, что вроде бы идет привязка к объекту user, тем не менее компонент получает значения его свойств по отдельности.
Как использовать пропсы для передачи данных дочерним компонентам в 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.х. Вы можете проверить установленную версию в терминале, выполнив команду:
Кроме того, вам понадобится текстовый редактор. Мы настоятельно рекомендуем VS Code. И наконец, вам необходим глобально установленный Vue 3. На момент написания статьи, актуальной является третья версия.
Прежде чем начать, скачайте стартовый проект Vue. Разархивируйте скачанный проект, перейдите в папку проекта, а затем выполните команду ниже для установки всех зависимостей:
Что такое пропсы в Vue?
Пропс в Vue — это кастомный атрибут, который вы можете зарегистрировать в любом компоненте. Вы определяете данные в родительском компоненте и присваиваете им определенное значение. Затем переходите в дочерний компонент, которому эти данные необходимы, и передаете значение атрибуту props. В результате данные становятся свойством дочернего компонента.
В компоненте, реализованном на Composition API, то есть с использованием , синтаксис будет выглядеть следующим образом:
Для компонентов, реализованных с помощью Options API:
export default < props: ['title'], setup(props) < // setup() принимает пропсы в качестве первого аргумента console.log(props.title) >>
Чтобы получить доступ к этим данным динамически из любого компонента, которому они нужны, вы можете использовать корневой компонент App.vue как родительский, хранить в нем данные, а затем регистрировать пропсы.
Зачем мне использовать пропсы?
Давайте представим, что у вас в есть объект с данными, которые вы хотите по-разному отобразить в двух разных компонентах. К примеру, пусть это будет топ-10 лучших исполнителей. Вполне вероятно, что в первую очередь вы подумаете о создании двух отдельных компонентов, в каждом из которых будет массив объектов с исполнителями и их отображение с помощью блока .
В данном случае это будет отличным решением, однако по мере масштабирования проекта и добавления все новых и новых компонентов, этот метод перестанет быть эффективным. Давайте убедимся в этом на примере стартового проекта, который вам нужно открыть с помощью VS Code. Откройте файл Test.vue и скопируйте в него код:
Создайте новый файл Test2.vue в папке Components и скопируйте в него код ниже:
Чтобы зарегистрировать новый компонент, который вы только что создали, откройте файл App.vue и скопируйте в него код:
<div >
В терминале VS Code запустите ваш проект локально, выполнив команду:
Результат в окне браузера должен быть следующим:
Вы заметите, что если вам понадобится создать еще 5 похожих компонентов, вы будете копировать данные в каждый компонент по отдельности. Однако существует возможность один раз объявить данные в родительском компоненте, а затем передавать их в каждый из дочерних компонентов с помощью пропсов.
Определение данных в родительском компоненте
В тот момент, когда вы выбрали корневой компонент в качестве родительского, вам в первую очередь необходимо определить объект с данными внутри него. Если вы продолжаете следить за тем, что мы делаем, откройте файл App.vue и скопируйте объект с данными в секцию .
Получение пропсов в Vue
После определения данных, перейдите в каждый из дочерних компонентов и удалите из них объекты data() вместе с их содержимым. Чтобы прокинуть пропсы в компонент, вы должны объявить пропсы, которые хотите получить, внутри каждого из компонентов. В каждом из Test -компонентов на месте объектов с данными, которые мы только что удалили, создайте новое свойство так, как показано ниже:
export default
Регистрация пропсов в Vue
Чтобы дать движку Vue понять, что у вас есть пропсы, которые вы динамически хотите передать в дочерние компоненты, вы должны сигнализировать об этом внутри родительского компонента. Сделать это можно в секции , как показано ниже:
В коде выше мы используем директиву v-bind , чтобы связать массив artists в родительском компоненте с пропсом artists , который находится в каждом из дочерних компонентов.
Если вы сделаете это без использования директивы, то никакого смысла в этом не будет. Будьте внимательны: ни компилятор Vue, ни ESLint не подсветят это как ошибку:
Поэтому так важно быть внимательным и помнить об использовании директивы v-bind для всех динамических связок.
Использование пропсов в Vue
После того как вы настроили пропсы в своем проекте Vue, вы можете использовать их внутри дочерних компонентов так, будто данные были объявлены внутри каждого из них. Это значит, что доступ к данным будет осуществляться с помощью this.artists .
Строго типизированные пропсы
При строгой типизации пропсов вы можете быть уверены, что дочерний компонент получит именно тот тип данных, который вам нужен. В стартовом проекте для созданных нами пропсов вы можете добавить условие, что в качестве пропсов могут быть переданы только массивы:
Как следствие, если вы попытаетесь передать пропсом неверный тип, например String , то в консоли появится сообщение об ошибке, которая укажет на несоответствие типов:
Заключение
В этой статье мы открыли для себя пропсы в Vue 3, выяснили, как они могут помочь соблюдать принцип DRY (не повторяйся) путем переиспользования объектов с данными. Мы также выяснили, как регистрировать и передавать пропсы внутри проекта Vue. Более подробную информацию о пропсах можно найти в официальной документации Vue. Удачи!
Спасибо за внимание! Надеемся, что этот перевод был полезен для вас.
Авторские материалы для разработчиков мы также публикуем в наших соцсетях – ВК и Telegram.
- Блог компании SimbirSoft
- Веб-разработка
- Программирование
- VueJS
Входные параметры
Подразумевается, что вы уже изучили и разобрались с разделом Основы компонентов. Если нет — прочитайте его сначала.
Стиль именования входных параметров (camelCase в сравнении с kebab-case)
Имена HTML-атрибутов являются регистро-независимыми, поэтому браузеры интерпретируют любые прописные символы как строчные. Это означает, что при использовании шаблонов в DOM входные параметры в camelCase-стиле должны использовать свои эквиваленты в стиле kebab-case (разделённые дефисами):
Vue.component('blog-post', {
// camelCase в JavaScript
props: ['postTitle'],
template: '{{ postTitle }}
'
})
blog-post post-title="hello!"> blog-post>
Опять же, если вы используете строковые шаблоны, то это ограничение не применяется.
Указание типа входных параметров
До сих пор мы видели только входные параметры, перечисленные в виде массива строк:
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
Однако лучше, когда каждый входной параметр будет определённого типа. В этих случаях вы можете перечислить входные параметры объектом, где свойство и значение будут содержать информацию об имени входного параметра и его типе, соответственно:
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // или любой другой конструктор
}
Это не только документирует ваш компонент, но также предупреждает пользователей в консоли JavaScript браузера, если они передают неправильный тип. Вы узнаете гораздо больше о проверках типов и других валидациях входных параметров дальше на этой странице.
Передача статических и динамических входных параметров
До сих пор вы встречали, что во входные параметры передавались статические значения, например:
blog-post title="My journey with Vue"> blog-post>
Вы также встречали входные параметры, присваивающие динамическое значение с помощью v-bind , например:
blog-post v-bind:title="post.title"> blog-post>
blog-post
v-bind:title="post.title + ' написанный ' + post.author.name"
> blog-post>
В этих двух примерах мы передаём строковые значения, но могут передаваться значения любого типа во входной параметр.
Передача чисел
blog-post v-bind:likes="42"> blog-post>
blog-post v-bind:likes="post.likes"> blog-post>
Передача булевых значений
blog-post is-published> blog-post>
blog-post v-bind:is-published="false"> blog-post>
blog-post v-bind:is-published="post.currentUserFavorited"> blog-post>
Передача массивов
blog-post v-bind:comment-ids="[234, 266, 273]"> blog-post>
blog-post v-bind:comment-ids="post.commentIds"> blog-post>
Передача объектов
blog-post
v-bind:author="{ name: 'Veronica', company: 'Veridian Dynamics' }"
> blog-post>
blog-post v-bind:author="post.author"> blog-post>
Передача свойств объекта
Если вы хотите передать все свойства объекта в качестве входных параметров, вы можете использовать v-bind без аргументов ( v-bind вместо v-bind:prop-name ). Например, для объекта post :
post: {
id: 1,
title: 'My Journey with Vue'
}
blog-post v-bind="post"> blog-post>
blog-post
v-bind:id="post.id"
v-bind:title="post.title"
> blog-post>
Однонаправленный поток данных
Все входные параметры образуют одностороннюю привязку между дочерним свойством и родительским: когда родительское свойство обновляется — оно будет передаваться дочернему, но не наоборот. Это предотвращает случайное изменение дочерними компонентами родительского состояния, что может затруднить понимание потока данных вашего приложения.
Кроме того, каждый раз, когда обновляется родительский компонент, все входные параметры дочернего компонента будут обновлены актуальными значениями. Это означает, что вы не должны пытаться изменять входной параметр внутри дочернего компонента. Если вы это сделаете, Vue отобразит предупреждение в консоли.
Обычно встречаются два случая, когда возникает соблазн изменять входной параметр:
props: ['initialCounter'],
data: function ( ) {
return {
counter: this.initialCounter
}
}
props: ['size'],
computed: {
normalizedSize: function ( ) {
return this.size.trim().toLowerCase()
}
}
Обратите внимание, что объекты и массивы в JavaScript передаются по ссылке, поэтому если входной параметр является массивом или объектом, то изменение объекта или массива внутри дочернего компонента будет влиять на состояние родителя.
Валидация входных параметров
Компоненты могут указывать требования к своим входным параметрам, такие как определение типа, которые вы уже видели. Если эти требования не выполнены — Vue предупредит вас сообщением в JavaScript-консоли браузера. Это особенно полезно при разработке компонента, который предназначен для использования другими.
Чтобы указать валидации входного параметра, вы можете предоставить в props объект с валидациями для проверки значения, вместо массива строк. Например:
Vue.component('my-component', {
props: {
// Просто проверка типа (`null` и `undefined` проходят проверку для любого типа)
propA: Number,
// Несколько допустимых типов
propB: [String, Number],
// Обязательное значение строкового типа
propC: {
type: String,
required: true
},
// Число со значением по умолчанию
propD: {
type: Number,
default: 100
},
// Объект со значением по умолчанию
propE: {
type: Object,
// Для объектов или массивов значения по умолчанию
// должны возвращаться из функции
default: function ( ) {
return { message: 'hello' }
}
},
// Пользовательская функция для валидации
propF: {
validator: function (value) {
// Значение должно соответствовать одной из этих строк
return ['success', 'warning', 'danger'].includes(value)
}
}
}
})
Когда валидация входного параметра заканчивается ошибкой — Vue выдаст предупреждение в консоли (если используется сборка для разработки).
Обратите внимание, что входные параметры валидируются перед созданием экземпляра компонента, поэтому свойства экземпляра (например, data , computed и т.д.) не будут доступны внутри default или функций validator .
Проверка типа
Значением type может быть один из следующих нативных конструкторов:
Кроме того, type также может быть пользовательской функцией-конструктором и валидация будет выполняться проверкой с помощью instanceof . Например, если существует следующая функция-конструктор:
function Person (firstName, lastName) {
this.firstName = firstName
this.lastName = lastName
}
Вы можете использовать:
Vue.component('blog-post', {
props: {
author: Person
}
})
чтобы проверить, что значение входного параметра author было создано с помощью new Person .
Передача обычных атрибутов
Обычные атрибуты — это атрибуты, передаваемые в компонент, но не имеющие определения соответствующего входного параметра в компоненте.
Хотя явно определённые свойства предпочтительны для передачи информации дочернему компоненту, авторы библиотек компонентов не всегда могут предвидеть все контексты, в которых будут использованы их компоненты. Вот почему компоненты могут принимать произвольные атрибуты, которые добавляются в корневой элемент компонента.
Например, представьте, что мы используем сторонний компонент bootstrap-date-input с плагином Bootstrap, который требует указания атрибута data-date-picker на элементе input . Мы можем добавить этот атрибут к нашему экземпляру компонента:
bootstrap-date-input data-date-picker="activated"> bootstrap-date-input>
И атрибут data-date-picker=»activated» будет автоматически добавлен в корневой элемент bootstrap-date-input .
Замена/Объединение существующих атрибутов
Представьте, что это шаблон для bootstrap-date-input :
input type="date" class="form-control">
Чтобы добавить тему для нашего плагина выбора даты, нам может понадобиться добавить определённый класс, например:
bootstrap-date-input
data-date-picker="activated"
class="date-picker-theme-dark"
> bootstrap-date-input>
В этом случае определены два разных значения для class :
- form-control , который задаётся компонентом в его шаблоне
- date-picker-theme-dark , который передаётся компоненту его родителем
Для большинства атрибутов значение, предоставляемое компоненту, будет заменять значение, заданное компонентом. Например, передача type=»text» будет заменять type=»date» и, вероятно, ломать всё! К счастью, работа с атрибутами class и style немного умнее, поэтому оба значения будут объединены в итоговое: form-control date-picker-theme-dark .
Отключение наследования атрибутов
Если вы не хотите, чтобы корневой элемент компонента наследовал атрибуты, вы можете установить inheritAttrs: false в опциях компонента. Например:
Vue.component('my-component', {
inheritAttrs: false,
// .
})
Это может быть особенно полезно в сочетании со свойством экземпляра $attrs , которое содержит имена атрибутов и значения, переданные компоненту, например:
{
required: true,
placeholder: 'Введите имя пользователя'
}
С помощью inheritAttrs: false и $attrs вы можете вручную определять к какому элементу должны применяться атрибуты, что часто требуется для базовых компонентов:
Vue.component('base-input', {
inheritAttrs: false,
props: ['label', 'value'],
template: `
{{ label }}
v-bind="$attrs"
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)"
>
`
})
Обратите внимание, что опция inheritAttrs: false не влияет на биндинги style и class .
Этот шаблон позволяет вам использовать базовые компоненты больше как обычные HTML-элементы, не беспокоясь о том, какой элемент будет у него корневым:
base-input
label="Пользователь:"
v-model="username"
required
placeholder="Введите имя пользователя"
> base-input>
Обнаружили ошибку или хотите добавить что-то своё в документацию? Измените эту страницу на GitHub! Опубликовано на Netlify .