Создание компонентов. Проброс содержимого




Создание компонентов

Сделаем основную разметку и подключим Vue:

<!DOCTYPE html> <html> <head> <title>eShop</title> </head> <body> <div id="app"> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> <script src="script.js"></script> </body> </html>

 

const app = new Vue({ el: '#app' });

 

Теперь объявим новый компонент. Для этого у Vue есть метод component(). Этот метод принимает два аргумента: название компонента и объект с настройками:

Vue.component('some', {});

 

Название может быть любым, но если оно состоит из нескольких слов, их принято разделять дефисом:

Vue.component('some-component', {});

 

Главный параметр компонента – template, html-разметка. Напишем что-нибудь простое:

Vue.component('some', { template: '<h1>Hi!</h1>' });

 

Теперь мы можем вызвать компонент в основном файле с разметкой:

... <div id="app"> <some-component></some-component> </div>...

 

Эта запись будет эквивалентна следующей:

... <div id="app"> <h1>Hi!</h1> </div>...

 

То есть Vue подставляет компонент туда, где его вызвали. Компонент можно использовать несколько раз:

... <div id="app"> <some-component></some-component> <some-component></some-component> <some-component></some-component> <some-component></some-component> </div>...

 

Этот код будет преобразован в следующий:

... <div id="app"> <h1>Hi!</h1> <h1>Hi!</h1> <h1>Hi!</h1> <h1>Hi!</h1> </div>...

 

Можно вызывать один компонент внутри другого:

Vue.component('some-component', { template: '<h1>Hi <another-component></another-component></h1>' }); Vue.component('another-component', { template: '<i>vue</i>' });

 

В итоге <some-component> превратится в такой html:

<h1>Hi! <i>vue</i></h1>

 

Проброс содержимого

Содержимое, которое находится между открывающим и закрывающим тегами компонента, можно пробрасывать внутрь и подставлять в шаблон. Для подстановки содержимого используется тег <slot>:

Vue.component('some-component', { template: '<h1><slot></slot></h1>' });

 

Теперь в основном файле вызовем этот компонент с разным содержимым:

... <div id="app"> <some-component>Here we go</some-component> <some-component>Here we go</some-component> <some-component>Here we go again</some-component> </div>...

 

Vue преобразует эту запись в

... <div id="app"> <h1>Here we go</h1> <h1>Here we go</h1> <h1>Here we go again</h1> </div>...

 

Работа с данными

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

Vue.component('some-component', { template: '<h1></h1>', data() { return { name: 'Frodo' } } });

 

Имя можно подставить в шаблон компонента, используя mustache-синтаксис:

Vue.component('some-component', { template: '<h1>{{ name }}</h1>', data() { return { name: 'Frodo' } } });

 

Ограничения шаблона

Важно помнить, что шаблон может содержать только один внешний элемент. Рассмотрим простейшую ситуацию:

// Работает Vue.component('some', { template: '<p></p>' });

 

Такой компонент будет работать нормально. Внутрь абзаца можно вложить другие элементы, и код тоже будет работать:

// Работает Vue.component('some', { template: ` <p> <span>Something</span> <span>Something else</span> </p> ` });

 

Но если мы добавим новый элемент на том же уровне, что и абзац, то Vue не сможет подставить шаблон:

// Не работает Vue.component('some', { template: ` <p></p> <p></p> ` });

 

Чтобы это исправить, нужно обернуть все элементы в один:

// Работает Vue.component('some', { template: ` <div> <p></p> <p></p> </div> ` });

 

Передача свойств

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

Vue.component('some-component', { template: '<h1>{{ name }}</h1>', data() { return { name: 'Frodo' } } });

 

Удалим из него поле data:

Vue.component('some-component', { template: '<h1>{{ name }}</h1>' });

 

Сейчас переменной name не существует, поэтому компонент выдаст ошибку. Объявим name как свойство при вызове компонента:

<div id="app"> <some-component name="Frodo Baggins"></some-component> </div>...

 

Но компонент будет выдавать ошибку и теперь. Свойство нужно объявить внутри компонента в поле props. В это поле передаётся массив с именами всех свойств:

Vue.component('some-component', { props: ['name'], template: '<h1>{{ name }}</h1>' });

 

Теперь значение свойства name будет подставляться в шаблон.

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

const app = new Vue({ el: '#app', data: { name: 'Frodo' } });

 

Передадим значение этой переменной в компонент:

... <div id="app"> <some-component v-bind:name="Frodo Baggins"></some-component> </div>...

 

У v-bind есть сокращённая запись. Можно опустить само ключевое слово v-bind и оставить только двоеточие:

... <div id="app"> <some-component:name="name"></some-component> </div>...

 

Практика

Вынесем список товаров и карточку товара интернет-магазина в отдельные компоненты. Создадим заготовки компонентов:

Vue.component('goods-list', { }); Vue.component('goods-item', { });

 

Начнём со списка. В первую очередь разберёмся, с какими данными ему предстоит работать. На вход он получит список filteredGoods:

... <main> <goods-list:goods="filteredGoods"></goods-list> </main>...

 

Теперь внутри div’а компонент будет создавать карточки товаров с помощью v-for и передавать информацию о товаре в компонент goods-item. Добавим это в шаблон:

Vue.component('goods-list', { props: ['goods'], template: ` <div class="goods-list"> <goods-item v-for="good in goods":good="good"></goods-item> </div> ` });

 

Перейдём к карточке товара. Здесь всё проще: на вход поступает объект с информацией о товаре, и мы просто подставляем в шаблон нужные поля:

Vue.component('goods-item', { props: ['good'], template: ` <div class="goods-item"> <h3>{{ good.product_name }}</h3> <p>{{ good.price }}</p> </div> ` });

 

Практическое задание

1. Вынести поиск в отдельный компонент.

2. Вынести корзину в отдельный компонент.

3. * Создать компонент с сообщением об ошибке. Компонент должен отображаться, когда не удаётся выполнить запрос к серверу.

 

Дополнительные материалы

1. Видеокурс по основам Vue.js.

 

Используемая литература

1. Официальная документация Vue.js.

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2021-12-05 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: