Введение в Vue.js: Vue-cli & Lifecycle Hooks

23.04.2017

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

Серия статей

  1. Рендеринг, директивы и события
  2. Components, Props и Slots
  3. Vue-cli (Вы здесь)
  4. Vuex
  5. Анимации

Vue-cli и процессы сборки

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

Vue предлагает действительно приятный cli, который даст вам работать с выбранными вами инструментами сборки, а так же простую стартовую заготовку. В первую очередь нужно установить vue-cli (-g поможет установить вам его глобально)

$ npm install -g vue-cli

Есть много доступных сборок, но в нашем примере мы будем использовать webpack:

$ vue init webpack

Следующими командами вы запишете и установите всё в каталог, а затем поднимите локальный dev сервер на localhost: 8080:

$ cd

$ npm install

$ npm run dev

Готово! Приятно, что установка настолько проста и чиста. Вы начнете с файла приложения в каталоге /src/ с ‘Hello.vue’ в каталоге /components/.

Давайте рассмотрим новое расширение файла ‘.vue’, потому что, если вы не работали с vue, то и не сталкивались с этим файлом раньше.

В файле ‘.vue’ вы можете разместить все необходимое для своего компонента. Нам больше не нужно оборачивать наши шаблоны в <script type = "text / x-template">, теперь мы будем более семантически создавать файлы, которые следуют этой логике:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
  <div>
    <slot></slot>
  </div>
</template>
 
<style scoped>
  .label {
    fill: black;
  }
  .bottle, .wine-text {
    fill: white;
  }
  .flor {
    fill: #ccc;
  }
  .bkimg {
    filter:url(#inverse)
  }
</style>

Я сделала репозиторий с Vue сниппетами для Sublime Text, чтобы быстро вставлять заготовки кода в файлы ‘.vue’, по типу того что выше (именно это и выведет сниппет vbase) . Есть еще для редактора Atom (но только на версию 1+, а Vue имеет уже вторую версию) и для vscode.

Здесь нужно обратить внимание на несколько вещей: как и в React, вы обязательно должны закрывать теги. Даже если в HTML допускается не закрывать некоторые, например <li>,<img>, <g> и т.п., в Vue каждый тег должен закрываться!

Вы увидите, что мы будем использовать экспорт по умолчанию для написания наших скриптов, таких как функция данных или методы, которые мы использовали ранее. Но если мы будем использовать компоненты как дочерние элементы в этом `.vue`, то нам также придется импортировать их (подробнее об этом через минуту).

Также заметьте, что мы имеем специальное scoped значение для тега style. Это позволяет нам охватить стили только для этого компонента. Использование просто <style> создало бы стили для всего приложения. Обычно я создаю базовый файл стилей для всего приложения, например с шрифтами и высотой строк, а затем импортирую в <style scoped> файла App.vue с помощью vue-style-loader. А уже после я использую тег <style scoped> для очень специфических стилей шаблона, если потребуется. Но на самом деле, можете делать как сами захотите. Приятно, что Vue-cli позволяет вам решить, как его организовать. И не нужно добавлять какие-либо зависимости или модули, чтобы наши стили работали таким образом.

Мы уже кратко говорили о слотах раньше. Теперь еще немного информации по слотам: когда мы используем слоты в компонентах с <style scoped>, то стили применяются к компоненту у которого есть слоты. Это очень полезно, ведь так вы можете переключать компоненты и легко менять их внешний вид.

Должна сказать, что с точки зрения рабочего процесса, работа в каждом конкретном файле `.vue` для моего HTML, стилей и JS была чрезвычайно полезна. Мне нравится, что вещи отделены друг от друга достаточно ясно, чтобы видеть структуру, но достаточно близко друг к другу, чтобы не терялся контекст. Это ускоряет разработку и при этом разметка остается довольно семантичной.

Можете также заметить, что подсветка синтаксиса не распознает файлы `.vue` автоматически, поэтому я установила это для Sublime Text.

Вот самый простой способ импорта / экспорта компонентов в файл (vimport:c в vue-sublime сниппете)

1
2
3
4
5
6
7
import New from './components/New.vue';
 
export default {
  components: {
    appNew: New
  }
}

Для более реалистичного примера, давайте посмотрим на образец последнего демо этикеток вин, которое мы использовали, с компонентами, выделенными в собственные шаблоны:

App.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<template>
  <div class="container">
 
  <main>
      <component :is="selected">
        <svg class="winebottle" aria-labelledby="title" xmlns="https://www.w3.org/2000/svg" viewBox="0 155 140 300">
          ...
      </svg>
      </component>
    </main>
 
    <aside>
      <h4>Name your Wine</h4>
      <input v-model="label" maxlength="18">
      <div class="button-row">
        <h4>Color</h4>
        <button @click="selected ='appBlack', labelColor = '#000000'">Black Label</button>
        <button @click="selected ='appWhite', labelColor = '#ffffff'">White Label</button>
        <input type="color" v-model="labelColor" defaultValue="#ff0000">
      </div>
    </aside>
 
  </div>
</template>
 
<script>
  import Black from './components/Black.vue'
  import White from './components/White.vue'
  ...
  export default {
      data: function () {
        return {
          selected: 'appBlack',
          label: 'Label Name',
          ...
        };
      },
      components: {
          appBlack: Black,
          appWhite: White,
          ...
      }
  }
</script>
 
<style>
  @import "./assets/style.css";
</style>

Black Component:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<template>
  <div>
    <slot></slot>
  </div>
</template>
 
<style scoped>
  .label {
    fill: black;
  }
  .bottle, .wine-text {
    fill: white;
  }
  .flor {
    fill: #ccc;
  }
  .bkimg {
    filter:url(#inverse)
  }
</style>

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

Lifecycle Hooks

Прежде чем мы поговорим о lifecycle hooks, нам нужно немного отступить и поговорить о виртуальном DOM, упомянутом в первой статье. Я отметила, что Vue.js имеет виртуальный DOM, но не то, что он делает.

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

Когда экземпляр Vue обновляется, Vue проверяет, отличается ли он от того, что было раньше. Если он действительно отличается, он вызовет некоторые из этих lifecycle методов и исправит актуальный DOM. Всё ради производительности. DOM обновляет только то, что ему абсолютно необходимо.

Lifecycle hooks предоставляют вам метод, позволяющий в точности вызвать что-либо на разных этапах жизненного цикла компонента. Компоненты монтируются, когда мы создадим их экземпляр и размонтируются, например, когда мы переключим их в операторе v-if / v-else.

Некоторые из доступных вам хуков: beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, activated, deactivated, beforeDestroy, и destroyed. API документация хорошо описывает каждую из них, если вы захотите копать дальше. Вот небольшое демо, чтобы показать, как некоторые из них работают (посмотрите консоль):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const Child = {
  template: '#childarea',
  beforeCreate() {
    console.log("beforeCreate!");
  }, 
 ...
};
 
new Vue({
  el: '#app',
  data() {
    return {
      isShowing: false 
    }
  },
  methods: {
    toggleShow() {
      this.isShowing = !this.isShowing;
    }
  },
  components: {
    appChild: Child
  }
});
1
2
3
<div v-if="isShowing">
  <app-child></app-child>
</div>

See the Pen wdWOPR by FurFurFur (@FurFurFur) on CodePen.29134

Обратите внимание, что мы используем v-if вместо v-show, поскольку v-if будет фактически монтировать и размонтировать компонент, в то время как v-show будет только переключаться с видимости (но он останется смонтированным и останется в DOM). Аналогично, не будет монтироваться или размонтироваться, а скорее активироваться и деактивироваться, поскольку компонент остается смонтированным, но не используется.

Подобно тому, как методы, доступные для компонента, привязываются автоматически, lifecycle hooks также автоматически привязываются к экземпляру, чтобы вы могли использовать и состояние компонента, и методы. Опять же, вам не нужно смотреть console.log, чтобы узнать на что ссылается this! По этой причине вам не следует использовать стрелочную функцию в lifecycle методе, поскольку она вернет родительский элемент вместо того, чтобы давать вам привязку из коробки.

В следующем примере я перемещаю тонну элементов, когда каждый компонент изначально установлен. Поэтому я буду использовать смонтированный хук для запуска соответствующей анимации для каждого компонента. Возможно, придется нажать кнопку «RERUN» в правом нижнем углу, чтобы увидеть анимацию.

See the Pen NjrJMm by FurFurFur (@FurFurFur) on CodePen.29134

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
mounted() {
    let audio = new Audio('https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/rain.mp3'),
        tl = new TimelineMax();
 
    audio.play();
    tl.add("drops");
 
    //drops in
    tl.staggerFromTo("#droplet-groups g path", 0.3, {
      drawSVG: "0% -10%"
    }, {
      drawSVG: "100% 110%",
      repeat: 3,
      repeatDelay: 1,
      ease: Sine.easeIn
    }, 0.5, "drops");}

Существуют также красивые и сложные компоненты и , но мы используем их в другом месте этой демонстрации. Мы рассмотрим их и то почему, как и когда использовать каждую из них в последней статье о Vue.js.

Серия статей

  1. Рендеринг, директивы и события
  2. Components, Props и Slots
  3. Vue-cli (Вы здесь)
  4. Vuex
  5. Анимации
Оригинальная статья: https://css-tricks.com/intro-to-vue-3-vue-cli-lifecycle-hooks/

1 комментарий

  1. @Алекс пишет:

    Класненькая статья, спасибо 🙂

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: