12 лучших практик Vue.js для профессиональных разработчиков

Введение

По мере того, как VueJS продолжает получать все большее распространение, появляется и становится стандартом ряд передовых методов.

Надеюсь, что эти лучшие практики помогут вам написать лучший код Vue.js. Это не только заставит всех ваших коллег-разработчиков полюбить вас, но и вы обязательно поблагодарите себя за то, что сделали вашу жизнь легче.

Ладно, хватит введения. Давайте начнем.

1. Всегда используйте :key внутри v-for

Использование ключевого атрибута с директивой v-for помогает вашему приложению быть постоянным и предсказуемым всякий раз, когда вы хотите манипулировать данными.

Это необходимо для того, чтобы Vue могла отслеживать состояние ваших компонентов, а также иметь постоянную ссылку на различные элементы. Примером, когда key чрезвычайно полезны, является использование анимации или переходов Vue.

Без ключей Vue просто попытается сделать DOM как можно более эффективным. Это может означать, что элементы в v-for могут появиться не в порядке, или их поведение будет менее предсказуемым. Если у нас есть уникальная ссылка на ключ для каждого элемента, то мы можем лучше предсказать, как именно наше приложение Vue будет обрабатывать манипуляции с DOM.

<!-- ПЛОХО -->
<div v-for="product in products">  </div>

<!-- ХОРОШО! -->
<div v-for="product in products" :key="product.id">

2. Используйте Kebab Case для Events

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

Поэтому для согласованности наших компонентов и для того, чтобы сделать ваш код более читабельным, используйте кебабный регистр в обоих местах.

this.$emit("close-window")

// затем у родителя

<popup-window @close-window="handleEvent()" />

3. Объявите Props с camelCase, и используйте Kebab Case в шаблонах

Эта передовая практика просто следует конвенциям для каждого языка. В JavaScript верблюжий кейс является стандартом, а в HTML - кебабный кейс. Поэтому мы используем их соответственно.

К счастью, для нас Vue.js конвертирует между kebab case и camelCase, так что нам не нужно беспокоиться ни о чем, кроме как о том, как их декларировать.

<!-- ПЛОХО! -->

<PopupWindow titleText="hello world" /> 

props: { "title-text": String }


<!-- ХОРОШО! -->

<PopupWindow title-text="hello world" /> 

props: { titleText: String }

4. Данные должны всегда возвращать функцию

При декларировании компонентных данных опция данных всегда должна возвращать функцию. Если нет, и мы просто возвращаем объект, то эти данные будут общими для всех экземпляров компонента.

// ПЛОХО!

data: {
  name: "My Window",
  articles: []
}

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

// ХОРОШО!

data () {
  return {
    name: "My Window",
    articles: []
  }
}

5. Не используйте v-if в сочетании с v-for элементом.

Очень заманчиво хотеть использовать v-if с v-for для фильтрации элементов массива.

<!-- ПЛОХО! -->

<div v-for="product in products" v-if="product.price < 500">

Проблема в том, что в Vue.js приоритет отдается директиве v-for, а не директиве v-if. Таким образом, под капотом она проходит через каждый элемент и then проверяет условие v-if.

this.products.map(function (product) {
  if (product.price < 500) {
    return product
  }
})

Это означает, что даже если мы хотим отрисовать только несколько элементов из списка, нам придется проциклировать весь массив.

Это нехорошо.

Более разумным решением было бы проведение итераций по вычисленному свойству. Приведенный выше пример выглядел бы примерно так.

<div v-for="product in cheapProducts">
computed: {
  cheapProducts: () => {
    return this.products.filter(function (product) {
      return product.price < 100
    })
  }
}

Это хорошо по нескольким причинам.

  • Рендеринг намного эффективнее, потому что мы не зацикливаемся на каждом элементе.
  • Отфильтрованный список будет пересматриваться только при изменении зависимости.
  • Это помогает отделить логику нашего компонента от шаблона, делая наш компонент более читабельным.

6. Проверьте свой Props на правильное определение.

Это, пожалуй, самая важная лучшая практика, которой следует следовать.

Почему это важно?

Ну, в основном, это спасает будущего тебя от нынешнего тебя. При проектировании крупномасштабного проекта легко забыть точный формат, тип и другие условности, которые вы использовали для реквизита.

И если вы в большой команде разработчиков, ваши коллеги не читают мысли, так что объясните им, как использовать ваши компоненты.

Так что избавьте всех от необходимости кропотливо отслеживать ваш компонент, чтобы определить формат реквизита, и, пожалуйста, просто напишите валидацию реквизита.

Посмотрите на этот пример из документов Vue.

props: {
  status: {
    type: String,
    required: true,
    validator: function (value) {
      return [
        "syncing",
        "synced",
        "version-conflict",
        "error"
      ].indexOf(value) !== -1
    }
  }
}

7. Используйте PascalCase или Kebab Case для компонентов

Общее соглашение об именовании компонентов заключается в использовании регистров PascalCase или Keybab. Независимо от того, какой из них вы выберете для своего проекта, самое главное, чтобы вы всегда оставались последовательными.

На мой взгляд, PascalCase работает лучше всего, потому что он поддерживается большинством автозавершенных функций IDE.

# ПЛОХО

mycomponent.vue
myComponent.vue
Mycomponent.vue


# ХОРОШО

MyComponent.vue

8. Базовые компоненты должны быть предварительно зафиксированы соответствующим образом.

Другое соглашение об именовании сосредоточено на именовании базовых компонентов - или компонентов, которые являются чисто презентационными и помогают установить общие стили в вашем приложении.

Согласно руководству по стилям Vue, базовые компоненты - это компоненты, которые содержат только:

  • элементы HTML
  • дополнительные базовые компоненты
  • сторонние компоненты пользовательского интерфейса

Лучшая практика именования этих компонентов - дать им префикс Base, V, или App. Еще раз повторюсь, что можно использовать любой из этих компонентов, пока вы придерживаетесь последовательности на протяжении всего проекта.

BaseButton.vue
BaseIcon.vue
BaseHeading.vue

Цель этого соглашения об именовании заключается в том, чтобы ваши базовые компоненты были сгруппированы в алфавитном порядке в вашей файловой системе. Кроме того, с помощью функции импорта Webpack, вы можете искать компоненты, соответствующие вашему шаблону именования-конвенции, и автоматически импортировать их все как глобальные компоненты в вашем проекте Vue.

9. Компоненты, объявленные и использованные один раз, должны иметь префикс "The".

Подобно базовым компонентам, однократные компоненты (используемые один раз на странице и не принимающие никакого реквизита) имеют свое собственное соглашение об именовании.

Эти компоненты специфичны для вашего приложения и, как правило, представляют собой заголовок, боковую панель или нижний колонтитул.

Должен быть только один активный экземпляр этого компонента.

TheHeader.vue
TheFooter.vue
TheSidebar.vue
ThePopup.vue

10. Используйте сокращенные директивы

Распространенной методикой среди разработчиков Vue является использование сокращения для директив. Например:

  • @ сокращение от v-on
  • : сокращение от v-bind
  • # сокращение от v-slot

Здорово использовать эти сокращения в вашем проекте Vue. Но чтобы создать что-то вроде конвенции в вашем проекте, вы должны либо всегда использовать их, либо никогда их не использовать. Это сделает ваш проект более сплочённым и читабельным.

11. Не вызывайте методы в "created" и "watch"

Обычная ошибка, которую допускают разработчики Vue (или, может быть, это был только я), это то, что они без необходимости вызывают метод в created и watch. Мысль, стоящая за этим, заключается в том, что мы хотим запустить watch крюк, как только компонент инициализирован.

// ПЛОХО!

created: () {
  this.handleChange()
},
methods: {
  handleChange() {
    // stuff happens
  }
},
watch () {
  property() {
    this.handleChange()
  }
}

Однако у Vue для этого есть встроенное решение. Это свойство Vue watchers, о котором мы часто забываем.

Все, что нам нужно сделать, это немного реструктурировать нашего Watchcher и объявить две собственности:

  1. handler (newVal, oldVal) - это наш метод наблюдения.
  2. immediate: true - это делает наш обработчик запущенным при создании нашего экземпляра.
// ХОРОШО!

methods: {
  handleChange() {
    // всякое бывает
  }
},
watch () {
  property {
    immediate: true
    handler() {
      this.handleChange()
    }
  }
}

12. Выражения шаблона должны иметь только базовые выражения JavaScript

Естественно желание добавить как можно больше встроенной функциональности в ваши шаблоны. Но это делает наш шаблон менее декларативным и более сложным. Это означает, что наш шаблон просто становится чрезвычайно загроможденным.

Для этого давайте рассмотрим другой пример нормализации строки из руководства по стилям Vue. Посмотрите, как это сбивает с толку.

// ПЛОХО!

{{
  fullName.split(" ").map(function (word) {
    return word[0].toUpperCase() + word.slice(1)
  }).join(" ")
}}

По сути, мы хотим, чтобы все в нашем шаблоне было интуитивно понятно, что он отображает. Чтобы сохранить это, мы должны рефакторизовать сложные выражения в соответствующим образом названные опции компонентов.

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

// ХОРОШО!

{{ normalizedFullName }}

// Сложное выражение было перемещено в вычисленное свойство
computed: {
  normalizedFullName: function () {
    return this.fullName.split(" ").map(function (word) {
      return word[0].toUpperCase() + word.slice(1)
    }).join(" ")
  }
}

источник: https://learnvue.co/2020/01/12-vuejs-best-practices-for-pro-developers/