Компоненты vue в html

# Основы компонентов

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

Компоненты — переиспользуемые экземпляры со своим именем: для примера выше это . Его можно использовать как пользовательский тег в корневом экземпляре:

div id="components-demo"> button-counter>button-counter> div> 

Поскольку компоненты это переиспользуемые экземпляры, то у них могут быть те же опции что и у корневого экземпляра: data , computed , watch , methods , хуки жизненного цикла.

# Переиспользование компонентов

Компоненты можно повторно использовать столько раз, сколько потребуется:

div id="components-demo"> button-counter>button-counter> button-counter>button-counter> button-counter>button-counter> div> 

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

# Организация компонентов

Обычно приложение организуется в виде дерева вложенных компонентов:

Дерево компонентов

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

Чтобы использовать компоненты в шаблонах, сначала их нужно зарегистрировать, чтобы Vue узнал о них. Есть два типа регистрации компонентов: глобальная и локальная. Ранее компоненты регистрировались только глобально, используя метод приложения component :

const app = Vue.createApp(>) app.component('my-component-name',  // . опции . >) 

Глобально зарегистрированные компоненты можно использовать в шаблоне любого компонента в приложении.

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

# Передача данных в дочерние компоненты через входные параметры

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

Входные параметры — пользовательские атрибуты, которые указываются на компоненте. Чтобы передавать заголовок в компонент записи блога, нужно определить его в списке входных параметров, которые принимает компонент, с помощью опции props :

const app = Vue.createApp(>) app.component('blog-post',  props: ['title'], template: `h4>< title >>h4>` >) app.mount('#blog-post-demo') 

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

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

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

div id="blog-post-demo" class="demo"> blog-post title="My journey with Vue">blog-post> blog-post title="Blogging with Vue">blog-post> blog-post title="Why Vue is so fun">blog-post> div> 

Скорее всего в типичном приложении наверняка будет массив записей в свойстве data :

const App =  data()  return  posts: [  id: 1, title: 'My journey with Vue' >,  id: 2, title: 'Blogging with Vue' >,  id: 3, title: 'Why Vue is so fun' > ] > > > const app = Vue.createApp(App) app.component('blog-post',  props: ['title'], template: `h4>< title >>h4>` >) app.mount('#blog-posts-demo') 

А значит для каждого из элементов массива потребуется отрисовать свой компонент :

div id="blog-posts-demo"> blog-post v-for="post in posts" :key="post.id" :title="post.title" >blog-post> div> 

Как видно в примере, можно использовать v-bind для динамической передачи входных параметров. Это полезно, когда заранее неизвестно точное содержимое для отрисовки.

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

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

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

Для этого добавим свойство postFontSize в родительском компоненте:

const App =  data()  return  posts: [ /* . */ ], postFontSize: 1 > > > 

И воспользуемся им в шаблоне чтобы установить размер шрифта для всех записей блога:

div id="blog-posts-events-demo"> div :style="< fontSize: postFontSize + 'em' >"> blog-post v-for="post in posts" :key="post.id" :title="post.title" >blog-post> div> div> 

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

app.component('blog-post',  props: ['title'], template: ` div class="blog-post"> h4>< title >>h4> button> Увеличить размер текста button> div> ` >) 

Проблема пока в том, что эта кнопка ничего не делает:

button> Увеличить размер текста button> 

При нажатии на кнопку нужно каким-то образом сообщать родительскому компоненту, что требуется увеличить размер текста для всех записей блога. Для решения этой проблемы, экземпляры компонента предоставляют собственную систему событий. Родительский компонент может прослушивать любые события на экземпляре дочернего компонента с помощью v-on или @ , аналогично отслеживанию нативных событий DOM:

blog-post . @enlarge-text="postFontSize += 0.1">blog-post> 

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

button @click="$emit('enlargeText')"> Увеличить размер текста button> 

Благодаря прослушиванию события @enlarge-text=»postFontSize += 0.1″ в родительском компоненте, получится отследить его и обновить postFontSize новым значением.

Все генерируемые компонентом события можно указать в опции emits :

app.component('blog-post',  props: ['title'], emits: ['enlargeText'] >) 

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

# Передача данных вместе с событием

Иногда полезнее вместе с событием отправить какие-либо данные. Например, если решим, что компонент будет отвечать за то, насколько следует увеличить текст. Тогда для передачи этого значения можно использовать второй параметр $emit :

button @click="$emit('enlargeText', 0.1)"> Увеличить размер текста button> 

Теперь, при прослушивании события в родительском компоненте, доступ к этому значению можно будет получить через специальную переменную $event :

blog-post . @enlarge-text="postFontSize += $event">blog-post> 

А если обработчик события будет указан именем метода:

blog-post . @enlarge-text="onEnlargeText">blog-post> 

То это значение будет передано в него первым аргументом:

methods:  onEnlargeText(enlargeAmount)  this.postFontSize += enlargeAmount > > 

# Использование v-model на компонентах

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

выполняет то же самое, что и:

input :value="searchText" @input="searchText = $event.target.value" /> 

Использование v-model на компоненте будет выполнять следующее:

custom-input :model-value="searchText" @update:model-value="searchText = $event" >custom-input> 

Обратите внимание, model-value указывается в kebab-case, потому что работаем с DOM-шаблонами. Подробнее об использовании атрибутов в kebab-case или camelCase объясняется в разделе особенностей парсинга DOM-шаблона

Однако для того, чтобы это всё заработало, внутри компонента должен:

  • Привязывать к значению атрибута value входной параметр modelValue
  • При событии input генерировать событие update:modelValue с новым значением
app.component('custom-input',  props: ['modelValue'], emits: ['update:modelValue'], template: ` input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" /> ` >) 

Теперь такой компонент будет прекрасно работать с v-model :

custom-input v-model="searchText">custom-input> 

Другим способом реализации v-model в компоненте будет использование вычисляемых свойств и их возможностей определить геттер и сеттер. Метод get должен возвращать свойство modelValue , а метод set генерировать соответствующее событие:

app.component('custom-input',  props: ['modelValue'], emits: ['update:modelValue'], template: ` input v-model="value"> `, computed:  value:  get()  return this.modelValue >, set(value)  this.$emit('update:modelValue', value) > > > >) 

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

# Распределение контента слотами

Как и в случае с обычными HTML-элементами, часто бывает полезным иметь возможность передавать компоненту содержимое, например таким образом:

alert-box> Произошло что-то плохое. alert-box> 

Чтобы в итоге всё выглядело примерно так:

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

app.component('alert-box',  template: ` div class="demo-alert-box"> strong>Ошибка!strong> slot>slot> div> ` >) 

Как можно увидеть выше, слот будет использоваться в качестве места, куда потребуется подставлять контент — и это всё. Готово!

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

# Динамическое переключение компонентов

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

Это возможно сделать с помощью элемента со специальным атрибутом is :

 component :is="currentTabComponent">component> 

В примере выше значением currentTabComponent может быть:

(opens new window) чтобы поэкспериментировать с полным кодом, или эту версию

(opens new window) с примером привязки объекта с настройками компонента вместо указания его имени.

Можно также использовать атрибут is и для создания обычных HTML-элементов.

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

# Особенности парсинга DOM-шаблона

Если пишете шаблоны Vue непосредственно в DOM, то Vue придётся получать строковый шаблон из DOM. Это приводит к некоторым особенностям, связанным с собственным поведением браузеров при парсинге HTML.

Следует отметить, что ограничения, обсуждаемые ниже, применимы только в том случае, если пишете шаблоны непосредственно в DOM. Таких ОГРАНИЧЕНИЙ НЕ БУДЕТ при использовании строковых шаблонов из следующих источников:

# Ограничение по расположению элементов

Это может привести к проблемам при использовании компонентов с элементами у которых есть такие ограничения. Например:

table> blog-post-row>blog-post-row> table> 

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

table> tr is="vue:blog-post-row">tr> table> 

При использовании на нативных HTML-элементах значение is должно начинаться с префикса vue: , чтобы интерпретироваться как компонент Vue. Это нужно чтобы избежать путаницы с нативными пользовательскими встроенными элементами

# Отсутствие чувствительности к регистру

Имена атрибутов HTML не чувствительны к регистру, поэтому браузеры будут интерпретировать любые заглавные символы как строчные. А значит, при использовании DOM-шаблонов, необходимо указывать имена входных параметров в camelCase и обработчики событий в kebab-case (разделённые дефисом) эквивалентах:

// camelCase в JavaScript app.component('blog-post',  props: ['postTitle'], template: ` h3>< postTitle >>h3> ` >) 
 blog-post post-title="hello!">blog-post> 

Для начала это всё, что нужно знать об особенностях парсинга DOM-шаблонов — и вообще-то это окончание раздела Основы. Наши поздравления! Хоть ещё есть чему поучиться, но сначала рекомендуем отвлечься и попробовать поиграться с Vue и самостоятельно сделать что-нибудь интересное.

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

(opens new window)
Последнее обновление страницы: больше 1 года назад

Источник

Читайте также:  Как оформить программу на питон
Оцените статью