vue что такое props
В чём разница между props и data в Vue.js
Сначала это может сбивать с толку, потому что кажется, что они нужны для одного и того же. При этом не ясно, когда и что нужно использовать.
Так в чём же отличие между props и data?
Data — это приватное хранилище любого компонента, в котором вы можете хранить любые данные.
Props — то, как вы передаёте данные из родительского компонента в дочерний.
В этой статье вы узнаете:
Что такое props?
В Vue props — это способ передачи данных из родительского компонента ниже в дочерний.
Когда мы проектируем приложение, то в конечном итоге создаём структуру, называемую деревом. Это похоже на семейное дерево:
Данные передаются вниз от корневого компонента, который находится в самом верху. Похоже на то, как передаётся генетика из поколения в поколение, так же и родительские компоненты передают props дальше своим дочерним компонентам.
Во Vue мы добавляем props в компоненты в секции :
Однако, когда мы обращаемся к пропсам внутри компонента, то мы не можем их изменить, потому что не являемся их владельцами (точно также вы не можете изменить гены, которые вам передали родители).
Заметьте: на самом деле вы можете изменить пропсы, но это плохая идея, потому что вы также меняете и значение этих свойств у родителей, что может привести к путанице.
Что такое Data?
Data — это память каждого компонента. Это место, где вы можете хранить ваши данные и другие переменные, которые вам необходимы.
Если мы делаем приложение-счётчик, то мы будем отслеживать и хранить переменную-счётчик count в data :
Этот data-параметр является приватным и доступен только внутри компонента. Другие компоненты не имеют к нему доступа.
Заметьте: На самом деле вы можете получать доступ к этому data-параметру из других компонентов, но это очень-очень плохая идея. Не стоит так делать!
Если вам нужно передать данные между компонентами, то используйте props для передачи вниз по дереву (дочерним компонентам), или события для передачи вверх по дереву (родительским компонентам).
Props и Data реактивны
С Vue вам не нужно думать о том, когда компонент обновит сам себя и перерендерится с новыми данными. Всё потому, что Vue реактивный.
Вместо вызова setState в случае каких-то изменений, вы просто меняете это напрямую. Пока вы обновляете реактивные свойства (props, computed props и что-либо в data), Vue знает как следить за изменениями.
Возвращаясь к нашему приложению-счётчику, давайте посмотрим на методы:
Реактивность во Vue содержит гораздо больше нюансов, в которых стоит разобраться. Важно понимать как она работает, чтобы профессионально разрабатывать на Vue. Почитайте раздел о реактивности, чтобы погрузиться эту тему.
Предотвращение конфликта имён
Есть ещё одна вещь, которую делает Vue, что делает разработку ещё прекраснее.
Давайте определим некоторые props и data в компоненте:
Мы можем получить к ним доступ через this.propA или this.dataA :
Vue выдаст warning в такой ситуации, потому что не будет знать что конкретно вы имели ввиду и к чему пытались получить доступ в каждом конкретном случае.
Настоящая магия и чудо происходят в тот момент, когда вы используете props и data вместе.
Использование props и data вместе
Мы изучили, чем props и data отличаются. Давайте посмотрим на примере простого приложения, почему их стоит использовать одновременно.
Давайте представим, что мы делаем социальную сеть и работаем над страницей пользователя. Мы дошли до того момента, когда нам нужно вывести контактную информацию пользователя.
Мы будем отображать это с помощью компонента ContactInfo :
Компонент ProfilePage показывает фото и имя пользователя. Он также содержит объект с данными пользователя в data.
Для начала мы должны импортировать компонент ContactInfo в наш основной компонент ProfilePage :
Во-вторых, мы должны добавить компонент в секцию :
Поскольку данные (data) передаются только вниз, это означает, что мы должны помещать данные (data) достаточно высоко в дереве компонентов. Так мы будем иметь возможность передать все данные (data) с помощью свойств (props) в любой дочерний компонент.
# Входные параметры
Подразумевается, что уже изучили и разобрались с разделом Основы компонентов. Если нет — прочитайте его сначала.
# Указание типа входных параметров
До сих пор входные параметры видели только как перечисленные в виде массива строк:
Однако лучше, когда каждый входной параметр будет определённого типа. В этих случаях можно перечислить входные параметры объектом, где свойство и значение будут содержать информацию об имени входного параметра и его типе, соответственно:
Это не только документирует компонент, но также предупреждает пользователей в консоли JavaScript браузера, если они передают неправильный тип. Гораздо больше о проверках типов и других валидациях входных параметров узнаете дальше на этой странице.
# Передача статических и динамических входных параметров
До сих пор встречались с тем, что во входные параметры передавались статические значения, например:
В этих двух примерах передаются строковые значения, но могут передаваться значения любого типа во входной параметр.
# Передача чисел
# Передача булевых значений
# Передача массивов
# Передача объектов
# Передача свойств объекта
Если хотите передать все свойства объекта в качестве входных параметров, то можно использовать v-bind без аргументов ( v-bind вместо v-bind:prop-name ). Например, для объекта post :
Будет аналогичен такой записи:
# Однонаправленный поток данных
Все входные параметры образуют одностороннюю привязку между дочерним свойством и родительским: когда родительское свойство обновляется — оно будет передаваться дочернему, но не наоборот. Это предотвращает случайное изменение дочерними компонентами родительского состояния, что может затруднить понимание потока данных приложения.
Кроме того, каждый раз, когда обновляется родительский компонент, все входные параметры дочернего компонента будут обновлены актуальными значениями. Это означает, что не должны пытаться изменять входной параметр внутри дочернего компонента. Если это сделать, Vue отобразит предупреждение в консоли.
Обычно встречаются два случая, когда возникает соблазн изменять входной параметр:
Входной параметр используется для передачи начального значения; дочерний компонент хочет использовать его как локальное свойство данных в дальнейшем. В этом случае лучше всего определить локальное свойство в данных, которое использует значение входного параметра в качестве начального:
Входной параметр передаётся как необработанное значение, которое необходимо преобразовать. В таком случае лучше всего объявить вычисляемое свойство с использованием входного параметра:
Обратите внимание, что объекты и массивы в JavaScript передаются по ссылке, поэтому если входной параметр массив или объект, то изменения внутри дочернего компонента этого объекта или массива будет влиять на состояние родителя.
# Валидация входных параметров
Компоненты могут указывать требования к своим входным параметрам, такие как определение типа, которые уже видели выше. Если эти требования не выполнены — Vue предупредит сообщением в JavaScript-консоли браузера. Это особенно полезно при разработке компонента, который предназначен для использования другими.
Чтобы указать валидации входного параметра, можно предоставить в props объект с валидациями для проверки значения, вместо массива строк. Например:
Если валидация входного параметра заканчивается ошибкой, Vue выведет предупреждение в консоль (если используется сборка для разработки).
# Проверка типа
Значением type может быть один из следующих нативных конструкторов:
То можно использовать следующим образом:
# Регистр в именах входных параметров
Имена HTML-атрибутов не чувствительны к регистру, поэтому любые заглавные символы браузеры будут интерпретировать как строчные. Это значит, что при использовании шаблонов в DOM, входные параметры в camelCase должны быть указаны в kebab-case (разделённые дефисом) эквиваленте:
Опять же, при использовании строковых шаблонов это ограничение не применяется.
(opens new window)
Последнее обновление страницы: 4 дня назад
Входные параметры
Подразумевается, что вы уже изучили и разобрались с разделом Основы компонентов. Если нет — прочитайте его сначала.
Стиль именования входных параметров (camelCase в сравнении с kebab-case)
Имена HTML-атрибутов являются регистро-независимыми, поэтому браузеры интерпретируют любые прописные символы как строчные. Это означает, что при использовании шаблонов в DOM входные параметры в camelCase-стиле должны использовать свои эквиваленты в стиле kebab-case (разделённые дефисами):
Опять же, если вы используете строковые шаблоны, то это ограничение не применяется.
Указание типа входных параметров
До сих пор мы видели только входные параметры, перечисленные в виде массива строк:
Однако лучше, когда каждый входной параметр будет определённого типа. В этих случаях вы можете перечислить входные параметры объектом, где свойство и значение будут содержать информацию об имени входного параметра и его типе, соответственно:
Это не только документирует ваш компонент, но также предупреждает пользователей в консоли JavaScript браузера, если они передают неправильный тип. Вы узнаете гораздо больше о проверках типов и других валидациях входных параметров дальше на этой странице.
Передача статических и динамических входных параметров
До сих пор вы встречали, что во входные параметры передавались статические значения, например:
В этих двух примерах мы передаём строковые значения, но могут передаваться значения любого типа во входной параметр.
Передача чисел
Передача булевых значений
Передача массивов
Передача объектов
Передача свойств объекта
Если вы хотите передать все свойства объекта в качестве входных параметров, вы можете использовать v-bind без аргументов ( v-bind вместо v-bind:prop-name ). Например, для объекта post :
Однонаправленный поток данных
Все входные параметры образуют одностороннюю привязку между дочерним свойством и родительским: когда родительское свойство обновляется — оно будет передаваться дочернему, но не наоборот. Это предотвращает случайное изменение дочерними компонентами родительского состояния, что может затруднить понимание потока данных вашего приложения.
Кроме того, каждый раз, когда обновляется родительский компонент, все входные параметры дочернего компонента будут обновлены актуальными значениями. Это означает, что вы не должны пытаться изменять входной параметр внутри дочернего компонента. Если вы это сделаете, Vue отобразит предупреждение в консоли.
Обычно встречаются два случая, когда возникает соблазн изменять входной параметр:
Входной параметр используется для передачи начального значения; дочерний компонент хочет использовать его как локальное свойство данных в дальнейшем. В этом случае лучше всего определить локальное свойство в данных, которое использует значение входного параметра в качестве начального:
Входной параметр передаётся как необработанное значение, которое необходимо преобразовать. В этом случае лучше всего определить вычисляемое свойство с использованием входного параметра:
Обратите внимание, что объекты и массивы в JavaScript передаются по ссылке, поэтому если входной параметр является массивом или объектом, то изменение объекта или массива внутри дочернего компонента будет влиять на состояние родителя.
Валидация входных параметров
Компоненты могут указывать требования к своим входным параметрам, такие как определение типа, которые вы уже видели. Если эти требования не выполнены — Vue предупредит вас сообщением в JavaScript-консоли браузера. Это особенно полезно при разработке компонента, который предназначен для использования другими.
Чтобы указать валидации входного параметра, вы можете предоставить в props объект с валидациями для проверки значения, вместо массива строк. Например:
Когда валидация входного параметра заканчивается ошибкой — Vue выдаст предупреждение в консоли (если используется сборка для разработки).
Проверка типа
Значением type может быть один из следующих нативных конструкторов:
Вы можете использовать:
Передача обычных атрибутов
Обычные атрибуты — это атрибуты, передаваемые в компонент, но не имеющие определения соответствующего входного параметра в компоненте.
Хотя явно определённые свойства предпочтительны для передачи информации дочернему компоненту, авторы библиотек компонентов не всегда могут предвидеть все контексты, в которых будут использованы их компоненты. Вот почему компоненты могут принимать произвольные атрибуты, которые добавляются в корневой элемент компонента.
Замена/Объединение существующих атрибутов
Представьте, что это шаблон для bootstrap-date-input :
Чтобы добавить тему для нашего плагина выбора даты, нам может понадобиться добавить определённый класс, например:
В этом случае определены два разных значения для class :
Отключение наследования атрибутов
Если вы не хотите, чтобы корневой элемент компонента наследовал атрибуты, вы можете установить inheritAttrs: false в опциях компонента. Например:
Этот шаблон позволяет вам использовать базовые компоненты больше как обычные HTML-элементы, не беспокоясь о том, какой элемент будет у него корневым:
# Props
This page assumes you’ve already read the Components Basics. Read that first if you are new to components.
# Prop Types
So far, we’ve only seen props listed as an array of strings:
Usually though, you’ll want every prop to be a specific type of value. In these cases, you can list props as an object, where the properties’ names and values contain the prop names and types, respectively:
This not only documents your component, but will also warn users in the browser’s JavaScript console if they pass the wrong type. You’ll learn much more about type checks and other prop validations further down this page.
# Passing Static or Dynamic Props
So far, you’ve seen props passed a static value, like in:
You’ve also seen props assigned dynamically with v-bind or its shortcut, the : character, such as in:
In the two examples above, we happen to pass string values, but any type of value can actually be passed to a prop.
# Passing a Number
# Passing a Boolean
# Passing an Array
# Passing an Object
# Passing the Properties of an Object
If you want to pass all the properties of an object as props, you can use v-bind without an argument ( v-bind instead of :prop-name ). For example, given a post object:
The following template:
Will be equivalent to:
# One-Way Data Flow
All props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. This prevents child components from accidentally mutating the parent’s state, which can make your app’s data flow harder to understand.
In addition, every time the parent component is updated, all props in the child component will be refreshed with the latest value. This means you should not attempt to mutate a prop inside a child component. If you do, Vue will warn you in the console.
There are usually two cases where it’s tempting to mutate a prop:
Note that objects and arrays in JavaScript are passed by reference, so if the prop is an array or object, mutating the object or array itself inside the child component will affect parent state.
# Prop Validation
Components can specify requirements for their props, such as the types you’ve already seen. If a requirement isn’t met, Vue will warn you in the browser’s JavaScript console. This is especially useful when developing a component that’s intended to be used by others.
When prop validation fails, Vue will produce a console warning (if using the development build).
# Type Checks
The type can be one of the following native constructors:
In addition, type can also be a custom constructor function and the assertion will be made with an instanceof check. For example, given the following constructor function exists:
# Prop Casing (camelCase vs kebab-case)
HTML attribute names are case-insensitive, so browsers will interpret any uppercase characters as lowercase. That means when you’re using in-DOM templates, camelCased prop names need to use their kebab-cased (hyphen-delimited) equivalents:
Again, if you’re using string templates, this limitation does not apply.
Deployed on Netlify.
Caught a mistake or want to contribute to the documentation? Edit this on GitHub!
(opens new window)
Last updated: 2021-11-10, 01:51:22 UTC
Передача данных во Vue.js — как это работает?
Когда я изучал Vue, одной из самых сложных вещей было понимание того, как передавать данные во Vue. EventBus, Vuex, Props … Что это такое? Что из них я должен использовать?
Давайте узнаем их различия и когда нужно использовать каждый из них.
Внутри компонента
Это самое базовая использование Vue. Одна страница с одним компонентом. Это похоже на Vanilla Javascript с оттенком реактивности (как только вы изменяете объект, представление обновляется).
А вот и Javascript:
Как видите, все довольно просто. Здесь используются только два метода: первый для добавления, а второй для удаления задач.
В 23-й строке раздела HTML вы найдете функцию «on-click», которая переключает текущее задание между завершенным и незавершенным состояниями, а в строке 25 — другое, чтобы установить текущее задание для редактирования. Двухстороннее связывание данных делает все работу.
Методы взаимодействуют и изменяют данные (массив «todos»), достигая To-Do через «this». Как я уже сказал, это выглядит почти так же как если бы это был бы обычный Javascript.
Но что, если у нас есть два компонента в разных местах? Или три? Что, если один компонент является родительским для другого, и нам нужно передавать информацию между компонентами?
Допустим, у нас есть представление, разделенное на несколько компонентов, с дочерними компонентами внутри компонентов, вот как то так:
Как видите, оранжево-желтый основной компонент действует как корень каждого компонента. Внутри 3 компонента: красный, фиолетовый и зеленый. Некоторые из компонентов имеют дочерний компонент, что делает его веб-приложением 3 уровня.
Что делать, если вы хотите передать информацию из красного компонента в один из дочерних зеленых компонентов. Как бы вы это сделали?
Вы можете отправить информацию родителю с помощью $emit, а затем дочернему компоненту с помощью props. Это будет выглядеть как то так:
Вот как я использовал $emit и props:
Выглядит немного сложновато, но в действительности все довольно просто, когда вы освоитесь. Отправляйте свои данные с помощью $emit в верхний компонент, а вниз с помощью props.
Но что, если мы хотим отправить информацию между компонентами с несколькими уровнями между ними? Нам нужно будет использовать 4 $emits и 2 props?
Ну, конечно так можно сделать. Но это было бы сумасшествием.
Лучше в этом случае использовать EventBus.
EventBus — из любого места в любое место
Глобальный EventBus работает как «Родитель всех компонентов». Этот компонент имеет доступ ко всем компонентам, в которые он был загружен.
Вместо того, чтобы идти вверх и вниз по компонентам для отправки информации, мы можем отправить событие в EventBus и установить компоненты, которые мы хотим прослушивать для этого события.
Вот как это работает:
Намного проще, не правда ли? Просто добавьте компонент Vue с именем «EventBus» в ваш main.js и используйте его как способ отправки / получения сигналов от компонентов.
Хотя это отличный способ может работать с небольшими и средними приложениями, но более стандартный способ это использование Vuex
Vuex — наш менеджер состояний
Vuex — это шаблон управления состоянием Vue для приложений Vue.js.
Думайте о нем как о централизованном хранилище данных или «единственном источнике правды».
Vuex действует как единое центральное хранилище для всех компонентов в одном приложении. Кроме того, отслеживает все методы (или мутации) и помогает вам управлять всеми данными в вашем веб-приложении.
Если вы используете Vue Devtools, вы можете использовать их интересные функции, такие как отслеживание или просмотр всех данных, хранящихся в Vuex.
Здесь вы увидите запущенные методы, какие данные и методы которые в данный момент хранятся в хранилище Vuex, и сможете вернуться, чтобы проследить ваши шаги, изменить текущие данные и т. д.
Хотя веб-приложение несколько усложняется, добавлением накладных расходов, оно очень помогает разделить всю логику в один файл, предоставляя доступ к нескольким независимым компонентам и многому другому.
Давайте посмотрим, как я использовал его в реальной обстановке:
Снова довольно просто. Мы загружаем все функции и данные в файл store.js, который станет нашим «Единственным источником правды». Затем для каждого необходимого компонента мы загрузим нужные нам части.
Какой из подходов я должен использовать?
Вы можете использовать любой из них в своем проекте, но каждый подходит для любого сценария.
Опыт научит вас, когда использовать каждый из них.
Например, я использую Vuex в каждом приложении, даже в небольших (я люблю отслеживать свои данные), так же использую EventBus, чтобы запускать функции для определенных событий, когда я создаю компонент, который я использую несколько раз с различными данными.
Заключение
Читать (и писать) о том, какие методы обработки данных мы можем использовать, было круто, но вы должны практиковаться. Я написал небольшой пост, более ориентированный на код, чем этот, где я объяснял теорию. Вы можете прочитать о теории передачи данных здесь: Passing data in Vue
И, конечно же, у нас есть отличная документация по Vue: