Передача контента в слоты при монтировании

В Vue.js слоты используются для динамического внедрения контента в компоненты. Тестирование компонентов с использованием слотов является важной частью обеспечения корректной работы интерфейса. Vue Test Utils предоставляет гибкие инструменты для передачи контента в слоты при монтировании компонентов.

Монтирование компонента со стандартными слотами

Для передачи контента в стандартные (default) слоты используется опция slots при вызове функции mount:

import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'

const wrapper = mount(MyComponent, {
  slots: {
    default: '<p>Контент слота по умолчанию</p>'
  }
})

expect(wrapper.html()).toContain('<p>Контент слота по умолчанию</p>')

Ключевое здесь — объект slots, где имя свойства соответствует имени слота в компоненте. Для default слота используется ключ default. Переданный HTML автоматически рендерится внутри компонента.

Работа с именованными слотами

Именованные слоты позволяют вставлять контент в конкретные области компонента. В тестах их можно передавать аналогичным образом:

const wrapper = mount(MyComponent, {
  slots: {
    header: '<h1>Заголовок слота</h1>',
    footer: '<footer>Футер</footer>'
  }
})

expect(wrapper.find('h1').text()).toBe('Заголовок слота')
expect(wrapper.find('footer').text()).toBe('Футер')

Здесь ключи header и footer соответствуют name слотов в шаблоне компонента. Это обеспечивает точное тестирование контента, переданного в определенные области.

Передача компонентов в слоты

Слот может содержать не только HTML, но и другие Vue-компоненты. В тестах это реализуется с использованием компонентов в опции components:

import ChildComponent from '@/components/ChildComponent.vue'

const wrapper = mount(MyComponent, {
  slots: {
    default: ChildComponent
  }
})

expect(wrapper.findComponent(ChildComponent).exists()).toBe(true)

Также можно передавать контент в виде функции, что полезно для слотов с пропсами:

const wrapper = mount(MyComponent, {
  slots: {
    default: ({ msg }) => `<span>${msg}</span>`
  },
  props: {
    msg: 'Привет'
  }
})

expect(wrapper.html()).toContain('<span>Привет</span>')

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

Scoped слоты

Scoped слоты предоставляют данные из компонента в слот. Vue Test Utils позволяет тестировать их через функции:

const wrapper = mount(MyComponent, {
  scopedSlots: {
    default: `<template #default="{ text }"><p>{{ text }}</p></template>`
  }
})

expect(wrapper.find('p').text()).toBe('Ожидаемый текст')

Однако начиная с Vue 3 рекомендуется использовать обычные слоты через slots с функциями, так как опция scopedSlots устарела.

Динамический слот

Для тестирования компонентов с динамическими слотами удобно использовать функции, возвращающие содержимое:

const wrapper = mount(MyComponent, {
  slots: {
    default: ({ item }) => `<li>${item.name}</li>`
  },
  props: {
    items: [{ name: 'Элемент 1' }, { name: 'Элемент 2' }]
  }
})

const listItems = wrapper.findAll('li')
expect(listItems).toHaveLength(2)
expect(listItems[0].text()).toBe('Элемент 1')
expect(listItems[1].text()).toBe('Элемент 2')

Функции слотов позволяют полностью контролировать рендеринг, имитируя реактивные данные из компонента.

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

Vue Test Utils поддерживает передачу компонентов как слотов с помощью h или JSX, что особенно удобно для сложных структур:

import { h } from 'vue'

const wrapper = mount(MyComponent, {
  slots: {
    default: h('div', { class: 'custom' }, 'Контент')
  }
})

expect(wrapper.find('.custom').text()).toBe('Контент')

Использование h позволяет создавать компоненты и элементы напрямую, минуя строки HTML. Это особенно полезно для тестирования реактивных компонентов или функциональных слотов.

Проверка рендеринга слотов

Основные методы проверки:

  • wrapper.html() — возвращает весь HTML компонента.
  • wrapper.find(selector) — позволяет найти элемент по селектору и проверить его содержимое.
  • wrapper.findComponent(Component) — проверяет наличие переданного компонента.
  • wrapper.text() — возвращает текстовое содержимое компонента.

Эти методы совместно с передачей слотов обеспечивают детальное тестирование любых комбинаций контента.

Советы по передаче слотов

  1. Всегда использовать именованные слоты для сложных компонентов, чтобы легко проверять отдельные части.
  2. Использовать функции слотов для scoped данных, чтобы имитировать реальные пропсы.
  3. Передавать компоненты через h или JSX, когда требуется полный контроль над рендерингом и реактивностью.
  4. Комбинировать слоты и props, чтобы проверить взаимодействие данных компонента с переданным контентом.

Передача контента в слоты при монтировании — ключевой элемент тестирования Vue-компонентов. Правильная настройка слотов позволяет проверять как статический контент, так и динамические структуры, гарантируя корректность поведения интерфейса.