
Много свойств или свойство-объект: критерии выбора
Мы используя Vue, разрабатываем компоненты различного рода и условий применения. Одной из ключевых частей любых компонентов — это их интерфейс. Во Vue, передаваемые свойства — являются очень важной, если не самой важной, частью интерфейса компонента.
В ситуации, когда компонент требует множество данных, можно применить несколько способов их передачи. Рассмотрим их.
Набор свойств
Одним из возможных способов — это создать для каждого атомарного значения — отдельное свойство. Посмотрим на код компонента использующий подобный подход:
Шаблон
<template> <div> <div>First name: {{ firstName }}</div> <div>Last name: {{ lastName }}</div> <div>Birth year: {{ birthYear }}</div> </div> </template>
Скрипт
const MIN_BIRTH_YEAR = 1900 export default { name: 'PersonInfo', props: { firstName: { type: String, required: true, validator: firstName => firstName !== '' }, lastName: { type: String, required: true, validator: lastName => lastName !== '' }, birthYear: { type: Number, required: true, validator: year => year > MIN_BIRTH_YEAR && year < new Date().getFullYear() } } }
Посмотрим на использование этого компонента
<!-- Other part of html template--> <PersonInfo first-name="Jill" last-name="Smith" :birth-year="2000" /> <!-- Other part of html template-->
Рассмотрим преимущества и недостатки такого подхода
Преимущества
- Все свойства — независимы. При невалидности одного из значений — сообщение об ошибке будет более точным
- Наглядно содержание передаваемых свойств
- "Плоское лучше вложенного"
- Добавление новых необязательных свойств довольно легкое дело: просто добавляем свойство, которое использует параметр
default
props: { firstName: { type: String, required: true, }, lastName: { type: String, required: true, }, birthYear: { type: Number, required: true, validator: year => year > MIN_BIRTH_YEAR && year < new Date().getFullYear() }, city: { type: String, default: 'New York' } }
Недостатки
- Достаточно многословный код в родительском компоненте, особенно, когда данные берутся из одного объекта. Пример:
<!-- Other part of html template--> <PersonInfo :first-name="person.firstName" :last-name="person.lastName" :birth-year="person.birthYear" /> <!-- Other part of html template-->
- Многословность в определении свойств (в сравнении с описанием объекта)
Свойство-объект
Существуют ситуации, когда атомарными являются данные не примитивных типов. В заданном примере такими данными может быть объект person.
Рассмотрим пример:
Шаблон
<template> <div> <div>First name: {{ person.firstName }}</div> <div>Last name: {{ person.lastName }}</div> <div>Birth year: {{ person.birthYear }}</div> </div> </template>
Скрипт
import quartet from 'quartet' // npm validation package const v = quartet() const MIN_BIRTH_YEAR = 1900 export default { name: 'PersonInfo', props: { person: { type: Object, required: true, validator: v({ firstName: 'string', lastName: 'string', birthYear: v.and( 'safe-integer', v.min(MIN_BIRTH_YEAR), v.max(new Date().getFullYear()) ) }) } } }
Посмотрим на использование:
<!-- Other part of html template--> <PersonInfo :person="person"/> <!-- or (bad) --> <PersonInfo :person="{ firstName: 'Jill', lastName: 'Smith', birthYear: 2000 }"/> <!-- Other part of html template-->
Рассмотрим преимущества и недостатки
Преимущества
- Код в родительском компоненте становится короче
- При наличии определённой структуры данных, которая не меняется код становится менее избыточным
Недостатки
- Все значения становятся связанными одним объектом. При невалидности одного из значений — сообщение об ошибке будет говорить о невалидности всего объекта
- При использовании объекта в родительском компоненте: содержание передаваемых данных скрывается за абстракцией этого объекта
- Дополнительный уровень вложенности в компоненте
- Добавление новых необязательных свойств со значениями внутрь объекта невозможно (не знаю как это сделать)
- Для валидации объекта в той же степени, нужно использовать дополнительные инструменты валидации (напр. библиотеку валидации
quartet)
Выводы
Я пришел к таким выводам:
- использование отдельных свойств — более предпочтительно.
- Использование свойства-объекта допустимо, когда структура данных этого объекта не будет пополнятся дополнительными необязательными полями со значением по умолчанию.
P. S
Буду рад узнать ваши критерии выбора. Какой подход вы используете и почему? В прочем это и есть основная цель написания этой статьи. Может кто из вас знает лучшие практики и их обоснование? Спасибо, что уделили время.
Update 19:26, 16.01.2019
Также существует третий вариант c v-bind. Смотри обсуждение здесь
