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

Компоненты — это, по сути, многократно используемые экземпляры Vue, которым дается имя. Поскольку они являются экземплярами, они принимают те же параметры, что и new Vue, например data и computed, вместе с именем. Базовый формат выглядит следующим образом:

Vue.component('component-name', {
  data: function () {
    return {
      // some data
    }
  },
  template: `<div>
    <!-- some html-->
  </div>`
})

Чтобы разбить это, первый параметр, 'component-name', это имя, которое вы даете ему для ссылки на компонент, когда вы используете его в своем HTML. Вы должны дать ему имя, и объект, который вы передаете в качестве второй переменной, вероятно, должен иметь template с некоторым HTML, чтобы ваш компонент отображался на странице, когда вы его используете. Также рекомендуется использовать kebab-case для имени со всеми строчными буквами и дефисами, потому что это соответствует правилам для имен пользовательских тегов HTML.

Часть data — это данные, необходимые для компонента, и это всегда должна быть функция, которая возвращает объект с данными. Это делается для того, чтобы каждый отдельный экземпляр компонента имел собственную копию данных. Если бы он только что вернул объект data без функции, на каждый экземпляр компонента повлияло бы изменение data любого из них. Часть template компонента — это HTML, который вы хотите, чтобы ваш компонент имел. Обратите внимание, что шаблон заключен в обратные кавычки, а не в одинарные. Это связано с тем, что строка для template состоит из нескольких строк, поэтому вам нужно либо заключить ее в обратные кавычки, либо поставить обратную косую черту в конце каждой строки.

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

// in index.js
Vue.component('counter-component', {
  data: function () {
    return {
      count: 0
    }
  },
  template: `<div>
    <button v-on:click="count++">Click me!</button>
    <p>You've clicked the button {{ count }} times</p>
  </div>`
})
new Vue({
  el: '#component-example'
})
// in index.html
<div id='component-example'>
  <counter-component></counter-component>
</div>

Из этого примера видно, что вы можете использовать компонент на своей веб-странице, используя его имя, как если бы это был HTML-тег. И вы можете использовать каждый компонент столько раз, сколько захотите. Здесь следует отметить еще несколько вещей. Во-первых, вам нужно прикрепить экземпляр Vue к HTML, используя el, где вы хотите использовать компонент. В противном случае в этом случае div был бы пуст, потому что он не знает элемента с именем counter-component. Во-вторых, вам нужно, чтобы ваш template был обернут в один HTML-элемент. Если бы я убрал div из template в моем примере, это вызвало бы ошибку и не сработало бы.

Компоненты Vue в основном используются, когда вы пишете фрагмент HTML, который хотите использовать повторно. Например, профиль каждого пользователя сайта должен иметь одинаковое форматирование, поэтому мы хотим повторно использовать некоторый HTML, который будет одинаковым, за исключением данных, которые различаются от пользователя к пользователю, например, имя или адрес электронной почты. Но для этого нам нужен способ предоставить каждому использованию компонента различный набор информации. Это достигается с помощью так называемого реквизита. Реквизиты — это одна из опций, которые вы можете указать для компонента Vue, например:

Vue.component('profile', {
  props: ['name'],
  template: '<h3>{{ name }}</h3>'
})

Затем, чтобы передать ему имя, когда мы его используем, мы можем сделать это:

<profile name="Jane Doe"></profile>
<profile name="John Smith"></profile>
<profile name="Jesse Baker"></profile>

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

// in index.js
new Vue({
  el: '#people-list',
  data: {
    people: [
      { id: 1, name: 'Jane Do'},
      { id: 2, name: 'John Smith'},
      { id: 3, name: 'Jesse Baker'}
    ]
  }
})
// in index.html
<div id="people-list">
  <profile
    v-for="person in people"
    v-bind:key="person.id"
    v-bind:name="person.name"
  ></profile>
</div>

Как видно из этого примера, вы можете использовать v-bind для передачи динамических реквизитов, поэтому этот пример будет выглядеть точно так же на веб-странице, как и предыдущий, где я передал name вручную. Еще одна вещь, которую следует учитывать, это то, что по мере роста моего компонента profile ему, вероятно, потребуется больше реквизита. Но использовать v-bind снова и снова для большого количества реквизитов было бы утомительно, поэтому другой способ написать этот компонент profile будет таким:

// in index.js
Vue.component('profile', {
  props: ['person'],
  template: `<div>
    <h3>{{ person.name }}</h3>
    <img v-bind:src='person.img_url'></p>
    <p>{{ person.email }}</p>
  </div>`
})
// in index.html
<div id="people-list">
  <profile
    v-for="person in people"
    v-bind:key="person.id"
    v-bind:person="person"
  ></profile>
</div>

Последнее, о чем я расскажу о компонентах Vue, — это слоты. Вы могли заметить, что в примерах, которые я использовал, между открывающим и закрывающим тегами компонентов в HTML ничего нет. Это потому, что если вы попытаетесь поместить что-либо между открывающим и закрывающим тегами компонента, это не будет отображаться на странице. Но иногда вы можете захотеть поместить что-то между ними. Здесь на помощь приходят слоты. Они выглядят следующим образом:

// in index.js
Vue.component('navigation-link', {
  props: ['url'],
  template: `
    <a v-bind:href="url">
      <slot></slot>
    </a>
  `
})
// in index.html
<div id="profile-nav">
  <navigation-link url="/profile">
    Your Profile
  </navigation-link>
</div>

Из части, выделенной жирным шрифтом, вы можете видеть, что я добавил элемент slot, еще одну вещь, которую дает вам Vue. Теперь все, что вы пишете между тегами navigation-link, будет отображаться там, где вы помещаете элемент slot в компонент.

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