Слоты

Введение в слоты

Последнее обновление: 04.11.2020

Слоты предоставляют механизм создания фиксированной структуры компонента, в которой содержимое для различных частей компонента определяет родительский компонент. Во Vue 3 слоты реализуются через элемент <slot>, вместо которого родительский компонент вставляет содержимое в дочерний компонент.

Рассмотрим следующий пример:

<!DOCTYPE html>
<html>
<head>
<title>Слоты Vue 3</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
    <child-component><h2>Vue App</h2></child-component>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = Vue.createApp({});
 
app.component('child-component', { 
    template: `<div> <h3>Child Component</h3> </div>` 
});
app.mount('#app');
</script>
</body>
</html>

Здесь в коде html внутри элемента <child-component>, который представляет дочерний компонент, определено некоторое содержимое, а именно заголовок h2:

<child-component><h2>Vue App</h2></child-component>

Однако при рендеринге Vue полностью заменяет этот элемент со всем его содержимым на шаблон компонента, определенный параметром template:

Как работают слоты во Vue 3

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

<div id="app">
    <child-component><h2>Vue App</h2></child-component>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = Vue.createApp({});
 
app.component('child-component', { 
    template: `<div>
		<slot></slot>
		<h3>Child Component</h3>
	</div>` 
});
app.mount('#app');
</script>

При рендеринге вместо элемента slot в шаблоне дочернего компонента будет помещаться тот контент, который передал родительский компонент в дочерний - в данном случае это заголовок h2 <h2>Vue App</h2>:

Элемент slot и использование слотов в компонентах во Vue 3

При этом содержимое, помещаемое в слоты, может быть более сложным, нежели один элемент (как в даном случае заголовок h2), то есть этом может быть группа элементов. Кроме того, в шаблоне дочернего компонента мы можем много раз использовать элемент <slot>, и все эти вставки будут заменяться контентом, переданным из родительского компонента:

<div id="app">
    <child-component><h2>Vue App</h2><p>Это приложение Vue 3</p></child-component>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = Vue.createApp({});
 
app.component('child-component', { 
    template: `<div>
		<slot></slot>
		<h3>Child Component</h3>
		<slot></slot>
	</div>` 
});
app.mount('#app');
</script>
Множественное использование слотов в компонентах во Vue 3

Содержимое слотов по умолчанию

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

<!DOCTYPE html>
<html>
<head>
<title>Слоты Vue 3</title>
<meta charset="utf-8" />
</head>
<body>
<div id="app">
    <ads></ads>
    <ads> 
        <div>
            <p>Открыт набор на бесплатные курсы Udacity.</p>
            <p>Заявки принимаются до 16 октября</p>
        </div>
    </ads>
</div>
<script src="https://unpkg.com/vue"></script>
<script>
const app = Vue.createApp({});
 
app.component('ads', { 
  template: `<div> 
               <h3>Объявление</h3> 
               <slot>Здесь могла бы быть ваша реклама</slot>
             </div>` 
});
app.mount('#app');
</script>
</body>
</html>

Здесь определен компонент ads, который представляет блок под рекламное объявление. Само рекламное объявление будет добавляться в компонент через элемент <slot>. При этом на момент определения компонента мы можем не знать, а будет ли предоставлять какое-либо содержимое. Поэтому мы можем определить в элементе <slot> некоторое содержимое по умолчанию.

<slot>Здесь могла бы быть ваша реклама</slot>

При использовании компонента мы можем вложить в него некоторый контент, который будет вставляться в элемент <slot> и заменять в нем содержимое по умолчанию:

<div id="app">
	<ads></ads>
	<ads> 
		<div>
			<p>Открыт набор на бесплатные курсы Udacity.</p>
			<p>Заявки принимаются до 16 октября</p>
		</div>
	</ads>
</div>

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

Второй же компонент ads принимает контент и заменяет им содержимое в элементе <slot>.

Слоты в Vue 3
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850