Pull to refresh

Много свойств или свойство-объект: критерии выбора

Reading time3 min
Views4.1K


Много свойств или свойство-объект: критерии выбора


Мы используя 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. Смотри обсуждение здесь

Only registered users can participate in poll. Log in, please.
Какой подход предпочитаете использовать?
40.32% много свойств с примитивными значениями25
24.19% свойства-объекты15
32.26% И то, и другое (напишу критерии выбора в комментариях)20
3.23% Третье (напишу в комментариях)2
62 users voted. 22 users abstained.
Tags:
Hubs:
+6
Comments22

Articles