Чому props мають бути незмінними?
Props у Vue мають бути незмінними, тому що вони представляють дані, які контролюються батьківським компонентом, а не дочірнім. Якби дочірній компонент міг змінювати props напряму, це порушило б логіку застосунку, робило б дані непередбачуваними і призводило б до помилок.
Розберемо це максимально зрозуміло.
1. Односпрямований потік даних
Vue використовує модель:
Parent → ChildТобто:
- батько передає дані (props),
- дитина використовує ці дані, але не змінює їх.
Якби дочірній компонент міг змінювати props, виникла б плутанина:
- хто контролює дані?
- батько чи дитина?
Односпрямований потік робить систему передбачуваною та стабільною.
2. Якщо змінювати props - батько не дізнається про це
Приклад:
Батько:
<UserCard :name="userName" />Дитина:
props.name = 'New name' // поганоБатьківський стан userName не зміниться, хоча дитина змінила name.
У підсумку:
- у батька одне значення,
- у дитини інше,
- граф залежностей ламається.
3. Це порушує реактивність
Vue відстежує реакції на основі залежності props → template.
Якби компонент змінював props:
- Vue не зміг би коректно відстежувати, що змінилося,
- це створило б хаос в оновленні дерева компонентів.
4. Композиція компонентів стала б непередбачуваною
Уяви, що є ланцюжок:
App → UserList → UserCardЯкщо раптом UserCard почне змінювати свої props:
UserListне знатиме про зміни,App- теж,- оновлення UI стануть неконтрольованими.
Компоненти перестануть бути чистими, передбачуваними та ізольованими.
5. Props - це як аргументи функції
Якщо функція отримує аргумент:
function greet(name) {
name = 'John' // погано
}це теж вважається поганою практикою - аргументи мають бути незмінними.
Компоненти - ті ж функції, тільки візуальні.
6. Vue захищає props попередженням
Якщо спробувати змінити prop:
props.count++Vue видасть помилку:
[Vue warn]: Attempting to mutate prop "count".Це захист від неправильного використання.
Як правильно змінювати значення, що прийшли через props?
Спосіб 1. Використовувати локальний стан
Якщо значення потрібно змінити всередині компонента:
<script setup>
const props = defineProps(['initialValue'])
const value = ref(props.initialValue)
</script>Спосіб 2. Повідомляти батька через emit
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
function increment() {
emit('update:modelValue', props.modelValue + 1)
}
</script>Батько оновить стан → нове значення прийде назад через props.
Це і є односпрямований потік даних + двонаправлена взаємодія через події.
Підсумок (шпаргалка)
Чому props незмінні:
- Забезпечують односпрямований потік даних
- Батько залишається єдиним джерелом істини
- Реактивність працює коректно
- Компоненти залишаються передбачуваними
- Уникається плутанина між станами батька і дитини
- Vue попереджає про їх зміну
Якщо потрібно змінити дані - створи локальну копію або використай emit, щоб попросити батька змінити стан.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.