Директива v-show используется для условного отображения
элементов в DOM, изменяя их свойство display без удаления
из DOM. В отличие от v-if, который полностью добавляет или
удаляет элемент, v-show оставляет элемент в дереве,
управляя только стилями. Это накладывает особенности на тестирование,
так как проверка наличия элемента через стандартные методы типа
find() всегда будет успешной. Основной задачей становится
проверка видимости элемента.
v-show в тестахv-show управляет элементом через CSS-свойство
display. В Vue Test Utils можно получить доступ к этому
свойству через:
wrapper.find('селектор').element.style.display
Если директива установлена в true, значение
display должно быть пустым ('') или
соответствовать дефолтному стилю. Если false —
display: none.
v-show<template>
<div>
<p v-show="isVisible">Секретный текст</p>
<button @click="toggle">Переключить видимость</button>
</div>
</template>
<script>
export default {
data() {
return {
isVisible: false
}
},
methods: {
toggle() {
this.isVisible = !this.isVisible;
}
}
}
</script>
В данном компоненте <p> элемент изначально скрыт.
Тест должен проверить начальное состояние и реакцию на изменение
isVisible.
import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
const wrapper = mount(MyComponent)
v-showconst paragraph = wrapper.find('p')
expect(paragraph.isVisible()).toBe(false)
Метод isVisible() автоматически учитывает
display: none, visibility: hidden и другие
CSS-свойства, влияющие на видимость элемента. Это предпочтительный
способ для проверки v-show.
wrapper.vm.toggle()
await wrapper.vm.$nextTick()
expect(paragraph.isVisible()).toBe(true)
Важно использовать await wrapper.vm.$nextTick(), так как
изменения реактивных данных асинхронны и DOM обновляется только после
следующего тика.
Можно напрямую проверять стиль элемента:
expect(paragraph.element.style.display).toBe('none')
wrapper.vm.toggle()
await wrapper.vm.$nextTick()
expect(paragraph.element.style.display).toBe('')
Однако этот подход менее устойчив к изменениям CSS и менее
декларативен по сравнению с isVisible().
Если v-show зависит от вычисляемого свойства или
нескольких условий:
<p v-show="isVisible && userLoggedIn">Доступный контент</p>
Тест должен учитывать все комбинации:
wrapper.setData({ isVisible: true, userLoggedIn: false })
await wrapper.vm.$nextTick()
expect(wrapper.find('p').isVisible()).toBe(false)
wrapper.setData({ userLoggedIn: true })
await wrapper.vm.$nextTick()
expect(wrapper.find('p').isVisible()).toBe(true)
Методы setData и setProps позволяют
изменять реактивные данные и свойства компонента для проверки различных
сценариев.
Если изменение v-show связано с событием пользователя,
например кликом, важно моделировать событие:
const button = wrapper.find('button')
await button.trigger('click')
expect(wrapper.find('p').isVisible()).toBe(true)
Использование trigger() вместе с await
гарантирует корректное обновление DOM.
v-show часто комбинируется с transition. В
этом случае isVisible() учитывает анимацию только после
завершения перехода, если тест использует реальные DOM-объекты. Для
ускорения тестирования и исключения зависимостей от анимации можно
отключить transition:
import { mount } from '@vue/test-utils'
import MyComponent from '@/components/MyComponent.vue'
const wrapper = mount(MyComponent, {
global: {
stubs: {
transition: false
}
}
})
isVisible() для декларативной проверки
видимости, а не напрямую style.display.await wrapper.vm.$nextTick() после
изменения реактивных данных.v-show.trigger() для
динамических сценариев.Тестирование v-show требует внимания к DOM и
реактивности, но с использованием isVisible(),
setData и trigger() создаются устойчивые и
понятные тесты, отражающие поведение компонента в реальных условиях.