Перед вами вольный перевод статьи "10 Tips & Tricks to make you a better VueJS Developer" с сайта Dev.to. Автор расскажет нам об интересных и полезных вариантах применения привычных нам средств VueJS.


Введение


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


Сделаем красивым синтаксис слотов


С выходом в релиз Vue 2.6 стали доступны сокращения для слотов, что может быть использовано как эвенты (например сокращение @click для v-on:click) или двоеточие для биндинга данных (:src). Если у вас есть например табличный компонент, то вы можете использовать следующую фичу:


<template>
  ...
  <my-table>
    <template #row="{ item }">
      /* some content here. You can freely use 'item' here */
    </template>
  </my-table>
  ...
</template>

$on(‘hook:’)


Это крутая фича, которую вы можете использовать, если вам необходимо определить кастомный слушатель событий или сторонний плагин в хуках created или mounted и необходимо удалить его в хуке beforeDestroy, чтобы не допустить утечек памяти. Используя $on(‘hook:’) вы можете определить или удалить эвент всего в одном хуке.


mounted() {
 const aThirdPartyPlugin = aThirdPartyPlugin()
 this.$on('hook:beforeDestroy', () => {
  aThirdPartyPlugin.destroy()
 })
}

Валидация props


Возможно вы уже знаете, что есть возможность валидации ваших пропсов примитивными значениями, например String, Number или Object. Но вы также можете создать кастомный валидатор, например для проверки массива строк:


alertType: {
 validator: value => ['signup', 'login', 'logout'].includes(value)
}

Динамические аргументы директив


Одной из самых классный фич VueJS 2.6 является возможность динамического определения аргументов директив компонентов. Представим, что у вас есть компонент кнопка и вы хотите слушать событие Click при определенных условиях, а событие DoubleClick во всех остальных случаях. Вот случай, где такая директива может пригодиться:


<template>
  ...
  <aButton @[someEvent]="handleSomeEvent()"/>
  ...
</template>

<script>
  ...
  data(){
    return{
      ...
      someEvent: someCondition ? "click" : "dblclick"
    }
  },

  methods:{
    handleSomeEvent(){
      // handle some event
    }
  }
  ...
</script>

И что действительно здорово --> это то что вы можете применять этот шаблон к динамическим HTML атрибутам, пропсам и многому другому!


Переиспользование компонентов для схожих маршрутов


Иногда у вас есть разные маршруты, которые используют некоторый набор компонентов. Если вы переключаетесь между такими маршрутами, то по умолчанию общий компонент не будет перерисован, потому что Vue переиспользует этот компонент для лучшей производительности. Но если вы хотите перерисовывать эти компоненты, то можете определить свойство :key в Router-View-Component:


<template>
  <router-view :key="$route.fullPath"></router-view>
</template>

Передача всех пропсов из компонента родителя к дочернему


Это действительно крутая фича для передачи вниз всех пропсов из родительского компонента к дочернему. Такой способ удобен, если вы например используете компонент обертку. Таким образом вместо последовательной передачи всех свойств, вам достаточно передать их все одновременно:


<template>
  <childComponent v-bind="$props"/>
</template>

Вместо этого:


<template>
  <childComponent
    :prop1="prop1"
    :prop2="prop2"
    :prop3="prop3"
    :prop4="prop4"
    ...
  />
</template>

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


Если у вас есть дочерний компонент, который не является рутовым для компонента родителя, вы можете передать вниз все слушатели событий от родителя к потомку вот так:


<template>
  <div>
    ...
    <childComponent v-on="$listeners"/>
    ...
  </div>
</template>

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


$createElement


Каждый экземпляр Vue по умолчанию имеет доступ к методу $createElement, который создает и возвращает виртуальные узлы. Это может быть использовано например для использования разметки в методах, которые могут быть переданы в директиву v-html. В функциональных компонентах этот метод доступен, как первый аргумент функции render.


Использование JSX


Начиная с Vue CLI 3 по умолчанию появилась поддержка JSX. Теперь вы можете писать свой код с использованием JSX (например если вам так привычнее после реакта), также это может быть удобнее например для написания функциональных компонентов. Если вы еще не используете Vue CLI 3, то вы можете использовать babel-plugin-transform-vue-jsx для поддержки JSX в вашем проекте.


Кастомный v-model


По умолчанию v-model это то, что мы называем синтаксическим сахаром над событиями @input и :value. Но вы можете указать свойство model в вашем Vue компоненте и определить, какой эвент и пропс будет использован:


export default: {
 model: {
  event: 'change',
  prop: 'checked'
 }
}

Заключение


Я надеюсь, что смог дать вам несколько советов, которые помогут вам стать лучшим VueJS разработчиком.

Комментарии (15)


  1. vanxant
    12.10.2019 19:41

    Там где про динамические аргументы — это фича собственно js, а не vue


    1. mxmvshnvsk Автор
      12.10.2019 20:40

      Ну я так полагаю, что автор статьи просто показал, что так можно делать. Я много раз видел, как люди пишут что-то типа такого:

      ...
      <btn
        v-if=“statement”
        @click=“func”
      />
      <btn
        v-else
        @dbclick=“dbclickfunc”
      />
      ...
      


      1. vanxant
        12.10.2019 23:12

        но при этом второй (ваш) вариант выглядит понятнее и надёжнее (хотя и попахивает копипастой, да, если там много навешано)


  1. Gagydzer
    12.10.2019 20:30

    $createElement


    Вы пробовали вставить VNode как html-строку через v-html директиву? Какой результат?


    1. mxmvshnvsk Автор
      12.10.2019 20:34

      Не пробовал, но так полагаю, что заработает, так как эта директива просто реплейсит иннер ноду, но я в целом не пользуюсь возможностями v-html, так как это небезопасно.


      1. Gagydzer
        14.10.2019 09:53

        Не заработает.


  1. splinehip
    12.10.2019 22:55

    А у меня одного русскоязычная версия сайта vuejs.org не работает? Только через забугорный прокси открывается.


    1. delphinpro
      13.10.2019 00:25

      У меня она давно не работает в Опере. Но с того же компа прекрасно открывается в Хроме. Даже интересно, как такое может быть. Расширений для обхода блокировок нет ни в одном браузере.


      1. splinehip
        13.10.2019 02:37

        Действительно странно. У меня в хроме vuejs.org нормально работает, ru.vuejs.org не работает. В мозиле оба не работают.


    1. Metotron0
      13.10.2019 20:03

      На работе через Ростелеком большие проблемы с англоязычной версией и всё нормально с русской. Спасибо Роскомнадзору, я считаю.


      А статья на 80% состоит из материалов, которые расположены в самом начале гайда вуе. Я как раз конспект по нему делаю, поэтому в памяти всё это свежо.


      1. nur_timeline
        14.10.2019 09:12

        Произносится «Вью», Айван Ю сам говорил. Зачем ломать себе язык — «Вуе»!


        1. Metotron0
          14.10.2019 12:04

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


    1. Sid44
      14.10.2019 09:12

      У меня не работает сайт с докой по vue-router и babel. Через прокси всё нормально. Оперой пользуюсь


  1. Metotron0
    13.10.2019 20:28

    Хотелось бы под каждым таким пунктом, который повторяет документацию, иметь ссылку на конкретный раздел документации, чтобы там почитать поподробнее. Например я ещё не дошёл до синтаксиса #row="", поэтому не знаю, это способ что-то передать в слот или достать из него наружу внутреннюю переменную компонента, здесь в статье это не объясняется, поэтому хотелось бы сразу попасть в первоисточник.
    С $createElement тоже не понятно, про какую разметку в методах идёт речь. Разве в v-html передаются методы? Похоже на шпаргалку для тех, кто уже в теме, а не на статью для знакомства с чем-то незнакомым.


    1. mxmvshnvsk Автор
      14.10.2019 09:20

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

      Для этого пункта вот ссылка на документацию

      Например я ещё не дошёл до синтаксиса #row="", поэтому не знаю, это способ что-то передать в слот или достать из него наружу внутреннюю переменную компонента

      Эта директива по сути просто рисует переданный ей html элемент, это может быть как константа, реактивное свойство, так и значение, возвращаемое из метода. Вот ссылка на документацию или можно делать так
      Разве в v-html передаются методы?

      Тут речь вот про это
      С $createElement тоже не понятно, про какую разметку в методах идёт речь.