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

Пример использования слотов в Vue 3

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

<!-- MyButton.vue -->
<template>
    <button>
        <slot>Default Button Text</slot>
    </button>
</template>

В этом компоненте мы определяем слот <slot>, который по умолчанию выводит текст Default Button Text.

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

<!-- App.vue -->
<template>
    <div>
        <MyButton>Click me</MyButton>
    </div>
</template>

В этом примере мы передаем текст Click me в слот компонента MyButton. Таким образом, текст Click me будет отображаться на кнопке вместо текста по умолчанию.

Если мы не передаем текст в слот, то будет использоваться текст по умолчанию Default Button Text. Например:

<!-- App.vue -->
<template>
    <div>
        <MyButton></MyButton>
    </div>
</template>

В этом примере на кнопке будет отображаться текст Default Button Text.

Таким образом, слоты позволяют передавать контент из родительского (App.vue) компонента в дочерний компонент (MyButton.vue), что позволяет создавать более гибкие и переиспользуемые компоненты.

Пример генерации списка элементов

В этом примере мы используем слоты в компонентах List и App для генерации списка элементов в HTML-разметке.

Компонент List определяет список элементов, используя директиву v-for, которая генерирует 5 элементов с помощью цикла v-for="item in 5". Для генерации содержимого каждого элемента списка мы используем слоты.

<!-- List.vue -->
<template>
    <ul>
        <li v-for="item in 5" :key="item">
            <slot name="default" :iterable="item"></slot>
        </li>
    </ul>
</template>

Мы передаем в слот свойство iterable, значение которого определяется в директиве v-for. Значение item передается в слот через свойство iterable. Таким образом, в каждом элементе списка значение iterable будет соответствовать текущему значению item.

Компонент App использует компонент List и определяет слот #default, который генерирует содержимое каждого элемента списка.

<!-- App.vue -->
<template>
    <List>
        <template #default="{ iterable }">
            <span style="color: red">{{ iterable }}</span>
        </template>
    </List>
</template>

Данный код использует компонент List и через тег template рендерит слот #default, который будет генерировать содержимое каждого элемента списка.

Внутри компонента App мы передаем данные в компонент-потомок (List.vue) через слот #default="{ iterable }" используя свойство iterable для генерации содержимого каждого элемента списка. Внутри слота мы выводим значение iterable в теге красного цвета.

В итоге при рендеринге компонента List внутри компонента App мы получаем список, состоящий из 5 элементов, где каждый элемент содержит значение iterable, переданное через слот, и выводит его внутри тега красного цвета. В данном примере будут выведены числа от 1 до 5, красного цвета.

Что значит #default

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

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

Для определения слота по умолчанию в шаблоне Vue.js используется синтаксис #default. Например, если у нас есть компонент MyComponent, который содержит слоты с именами header и footer, мы можем определить слот по умолчанию следующим образом:

<MyComponent>
    <template #default>
        <p>Этот текст будет использоваться, если другой слот не определен.</p>
    </template>
</MyComponent>

В этом примере мы используем синтаксис #default для определения слота по умолчанию, который будет использоваться, если в компоненте MyComponent не определен слот с именем default.

Таким образом, если в компоненте-родителе нет определения для слота default, то в качестве его содержимого будет использовано содержимое, определенное в шаблоне слота по умолчанию.

Как понять #default="{ iterable }"

#default="{ iterable }" - это синтаксис шаблонов Vue.js для привязки данных, передаваемых через слот по умолчанию.

В данном случае, мы привязываем значение iterable к содержимому слота по умолчанию. Значение iterable передается из компонента List через атрибут iterable и доступно в шаблоне <template> компонента App через привязку данных { iterable }.

Таким образом, в этом примере мы передаем значение iterable из компонента List в компонент App через слот по умолчанию. Далее в шаблоне <template> компонента App мы используем значение iterable, чтобы отображать каждый элемент списка красным цветом.

Общий синтаксис для привязки данных в слотах выглядит так:

<slot name="my-slot" v-bind="{ data }"></slot>

Где data - это имя свойства данных, которые будут переданы в слот. Таким образом, мы можем передавать данные через слоты и использовать их во вложенных компонентах.

Почему { iterable } в фигурных скобках

{ iterable } в фигурных скобках - это синтаксис деструктуризации объекта в JavaScript.

В данном случае, мы используем деструктуризацию объекта для извлечения значения свойства iterable из объекта, передаваемого через слот по умолчанию в компоненте List. Значение свойства iterable затем привязывается к переменной с именем iterable в шаблоне компонента App.

Синтаксис деструктуризации объекта в JavaScript позволяет извлекать значения свойств объекта и привязывать их к переменным, используя фигурные скобки {}. Например, если у нас есть объект { name: 'John', age: 30 }, мы можем извлечь значения свойств, используя деструктуризацию объекта:

const { name, age } = { name: 'John', age: 30 }
console.log(name) // 'John'
console.log(age) // 30

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

Как использовать именованные слоты

Именованные слоты в Vue.js - это мощный механизм, который позволяет передавать содержимое между компонентами и настраивать его в разных местах.

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

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

Пример:

<!-- List.vue -->
<template>
    <ul>
        <slot name="item" v-for="item in items" :item="item">
            <!-- Если слот item не определен, отображаем значение item по умолчанию -->
            <li>{{ item }}</li>
        </slot>
    </ul>
</template>

<script>
    export default {
        props: {
            items: {
                type: Array,
                required: true
            }
        }
    }
</script>

В этом примере мы создаем компонент списка List, который принимает массив элементов items в качестве свойства. Внутри шаблона мы определяем именованный слот item, который будет использоваться для отображения каждого элемента списка. Мы используем директиву v-for для перебора элементов массива items и передаем каждый элемент через атрибут :item.

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

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

<!-- App.vue -->
<template>
    <div>
        <h2>My Todo List</h2>
        <List :items="todoList">
            <template #item="{ item }">
                <li :class="{ done: item.done }">{{ item.title }}</li>
            </template>
        </List>
    </div>
</template>

<script>
    import List from './List.vue'

    export default {
        components: { List },

        data() {
            return {
                todoList: [
                    { title: 'Task 1', done: true },
                    { title: 'Task 2', done: false },
                    { title: 'Task 3', done: false }
                ]
            }
        }
    }
</script>

Данный пример демонстрирует использование именованного слота item для отображения элементов списка дел в приложении Vue.js.

В шаблоне компонента App определяется список задач todoList, который передается в качестве пропса items компоненту List. Компонент List содержит именованный слот item, который позволяет настраивать отображение каждого элемента списка.

В шаблоне слота мы используем объект деструктуризации { item }, чтобы получить доступ к текущему элементу списка. Затем мы определяем стиль элемента списка в зависимости от его свойства done. Если done равно true, мы добавляем класс done к элементу списка, чтобы выделить выполненные задачи. В противном случае, элемент списка отображается без класса done.

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

Полученные знания и резюме

В данной статье были рассмотрены примеры кода, в которых использовались компоненты, слоты и другие элементы Vue.js.

В частности, были прояснены следующие моменты:

  • Как использовать слоты в компонентах Vue.js и передавать через них данные в компонент-потомок
  • Как в Vue.js использовать директиву v-for для генерации списков и управления содержимым элементов списка
  • Как работать с условными операторами и методами в Vue.js для управления отображением компонентов на странице
  • Как организовывать структуру проекта в Vue.js и разделять код на компоненты

Также были разобраны различные вопросы по синтаксису и функционалу Vue.js и даны подробные объяснения по каждому из них.

Написать комментарий