# Валидация props в Vue

05:36
poster
В этом видео мы с вами разберем, как валидировать props в Vue.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

В этом видео мы с вами разберем, как валидировать props в Vue. В данный момент у нас создан парент компонент App и чайлд компонент User, который получает из App props и рендерит их внутри себя. И он принимает такие props, как name, description и isActive.

Итак, главный вопрос сейчас, зачем нам валидировать props вообще и нужно ли это. Мы же можем просто посмотреть на массив props и понять, что нам необходимо передавать. Идея валидации props в том, чтобы знать, какие поля обязательны, а какие нет, и какие типы данных мы должны туда передавать.

Даже в маленьком проекте, который вы делаете один валидация может быть очень полезной и уберечь от багов. Например вы прочитали id из url, передали в компонент, забыв что из url вы прочитали не number, а string и пытаетесь найти этот элемент по id. И такие ошибки можно долго дебажить. Если же вы указали бы, что ваш компонент требует ID, который обязателен и должен быть Number, то такой ошибки не произошло бы.

Но давайте уже попробуем валидацию на практике. Давайте добавим upperCasedName метод, который будет переводить name в верхней регистр и отрендерим его в шаблоне вместо name.

User.vue

export default {
  ...
  methods: {
    upperCasedName () {
      return this.name.toUpperCase()
    }
  }
}
<h3>{{upperCasedName()}}</h3>

Теперь, если мы посмотрим в браузер, то все имена выводятся в верхнем регистре. Но что будет, если мы вызовем компонент user и не передадим в него name?

App.vue

<div>
  ...
  <my-user />
</div>

В браузере мы получили ошибку

Cannot read property 'toUpperCase' of undefined

Это происходит, потому что мы не передали name в User компонент. Поэтому мы должны добавить валидацию props в наш компонент. Например, было бы хорошо, если бы в name можно было передавать только строку и name был бы обязательным.

В Vue мы можем легко изменить наш массив props на обьект и написать типы каждого пропса.

User.vue

props: {
  name: String,
  description: String,
  isActive: Boolean
}

Что теперь будет, если мы попробуем передать Number в name?

App.vue

<my-user :name='1' />

Мы получаем красивый warning в консоли о том, что в name мы можем передавать только String.

[Vue warn]: Invalid prop: type check failed for prop "name". Expected String, got Number.

Это действительно помогает, чтобы защитить компонент от неправильных типов данных. Но это не решает нашу проблему с тем, что name undefined, поскольку в этом случае мы не получаем никаких warning.

Мы должны указать, что наш props name обязательный. И мы можем это сделать, просто изменив структуру наших props.

User.vue

props: {
  name: {
    type: String,
    required: true
  },
  description: String,
  isActive: Boolean
}

Вместо просто поля String мы указываем обьект с type и required. И тогда в браузере, мы получаем отличный warning

[Vue warn]: Missing required prop: "name"

Это действительно сразу помогает понимать, какие props нужно пробрасывать.

Но иногда мы также хотим указать props по умолчанию. Например, если мы не указали имя, то просто выводить 'Not set'. Мы можем это сделать, если укажем ключ default.

User.vue

name: {
  type: String,
  default: 'Not set'
}

Теперь, даже если мы не передаем name, то у нас ничего не падает, а используется значение по умолчанию.

На самом деле, если вы пришли из React, то валидация props в Vue очень простая, и в ней нельзя удобным образом указывать сложные конструкции. Можно, конечно, писать свои валидаторы, но код от этого чище не становится, хотя для простых приложений ее будет достаточно. Поэтому, если вы хотите типизированое приложение на Vue, то я бы посоветовал вам посмотреть в сторону Typescript либо Flow.

Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Moe Green
4 месяцев назад
как всегда очень наглядно и доступно )
monsterlessons
4 месяцев назад
На здоровье)