В Vue props представляют собой основной механизм
передачи данных от родительских компонентов к дочерним. Понимание их
реактивности критично для корректного построения компонентов и написания
тестов с использованием Vue Test Utils.
propsprops в Vue являются реактивными. Это означает, что
любые изменения их значений в родительском компоненте автоматически
отражаются в дочернем, если дочерний компонент использует эти
props.
Пример базового компонента:
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
props: {
message: {
type: String,
required: true
}
}
}
</script>
Если родительский компонент изменяет значение message,
это изменение автоматически отразится в шаблоне дочернего
компонента.
Важно помнить, что реактивность работает только в рамках
реактивной системы Vue. Присваивание нового объекта или массива
через props не меняет ссылку родительской переменной, а
лишь обновляет внутреннее представление в дочернем компоненте.
props с Vue Test UtilsVue Test Utils предоставляет методы для монтирования
компонентов и управления их props в тестовой
среде. Основные методы:
mount() — создаёт полный экземпляр компонента с
рендерингом DOM.shallowMount() — создаёт компонент без рендеринга
дочерних компонентов, полезно для изоляции.setProps() — изменяет props после
монтирования и запускает реактивное обновление.Пример теста реактивности:
import { mount } from '@vue/test-utils';
import MyComponent from '@/components/MyComponent.vue';
test('reactive props update DOM', async () => {
const wrapper = mount(MyComponent, {
props: { message: 'Initial' }
});
expect(wrapper.text()).toBe('Initial');
await wrapper.setProps({ message: 'Updated' });
expect(wrapper.text()).toBe('Updated');
});
Здесь ключевой момент — асинхронность обновлений.
Метод setProps() возвращает промис, который разрешается
после завершения реактивного обновления DOM. Использование
await гарантирует корректную проверку состояния компонента
после изменения props.
Props должны оставаться неизменяемыми внутри
компонента. Vue не запрещает изменение объекта, переданного
через props, но это нарушает концепцию однонаправленного
потока данных. Для тестов это значит, что проверка реактивности должна
идти через setProps() или родительский компонент.
Реактивность вложенных объектов. Если
prop — объект или массив, изменение вложенного свойства не
всегда триггерит обновление шаблона, если Vue не наблюдает за этим
свойством. Пример:
props: {
user: Object
}
// В тесте
await wrapper.setProps({ user: { name: 'Alice' } });
Если модифицировать только user.name напрямую
(wrapper.props().user.name = 'Bob'), Vue не гарантирует
обновления DOM. Рекомендуется использовать новый объект или
setProps().
props. Их
реактивность также тестируется через setProps(), учитывая,
что любое обновление props может изменить вычисляемое
значение и рендер.Иногда важно протестировать реакцию компонента на изменение props через события или методы. Например:
test('triggers method on prop change', async () => {
const wrapper = mount(MyComponent, { props: { count: 0 } });
const spy = jest.spyOn(wrapper.vm, 'handleCountChange');
await wrapper.setProps({ count: 5 });
expect(spy).toHaveBeenCalledWith(5);
});
Здесь показано, что метод handleCountChange вызывается
при изменении props. Это важно для компонентов с побочными
эффектами.
setProps() для всех изменений
props после монтирования.await.props.nextTick() при необходимости, если тест
проверяет несколько последовательных реактивных обновлений.props остаются источником правды для дочернего
компонента и автоматически обновляют шаблон при изменении.Реактивность props — фундаментальное свойство Vue, и её
правильное тестирование позволяет создавать стабильные и предсказуемые
компоненты, где данные обновляются строго по однонаправленному
потоку.