Ефекти та реактивність
1. Коротко: що таке effect
Effect (реактивний ефект) - це функція, яка повинна автоматично виконуватися щоразу, коли змінюються дані, від яких вона залежить.
Іншими словами, effect() - це "реактивний спостерігач".
Він запам'ятовує, які дані він використовує, і перезапускається, коли ці дані змінюються.
2. Приклад із життя
import { reactive, effect } from 'vue'
const state = reactive({ count: 0 })
effect(() => {
console.log(`Count: ${state.count}`)
})
state.count++ // "Count: 1" - effect спрацював зновуЩо тут відбувається:
- При першому виклику
effect()Vue запускає передану функцію. - Коли всередині функції зчитується
state.count, Vue "трекає" залежність (черезtrack()). - При зміні
state.countвикликаєтьсяtrigger()→ Vue "знає", що потрібно повторно запустити цейeffect.
Таким чином, effect = функція, яка автоматично реагує на зміни даних.
3. Як це працює під капотом
В основі реактивності - дві функції: track() і trigger().
// Спрощена модель
let activeEffect = null
const targetMap = new WeakMap()
function effect(fn) {
activeEffect = fn
fn() // запускаємо і трекаємо залежності
activeEffect = null
}
function track(target, key) {
if (!activeEffect) return
let depsMap = targetMap.get(target)
if (!depsMap) targetMap.set(target, (depsMap = new Map()))
let dep = depsMap.get(key)
if (!dep) depsMap.set(key, (dep = new Set()))
dep.add(activeEffect) // зберігаємо залежність
}
function trigger(target, key) {
const depsMap = targetMap.get(target)
if (!depsMap) return
const effects = depsMap.get(key)
effects && effects.forEach(fn => fn()) // запускаємо ефекти
}Логіка проста:
effect(fn)→ запускає функцію і запам'ятовує, які властивості вона читає.track()→ зберігає залежність між властивістю і ефектом.trigger()→ при зміні властивості викликає всі ефекти, що залежать від неї.
4. Ефекти бувають різних типів
У Vue є різні види ефектів, але всі вони засновані на одній системі:
| Тип ефекту | Що робить | Приклад |
|---|---|---|
| Render effect | Оновлює компонент, якщо змінилися дані, що використовуються в шаблоні | {{ count }} |
| Watch effect | Виконує побічні дії при зміні даних | watchEffect(() => console.log(state.count)) |
| Computed effect | Кешує результат обчислення, автоматично перераховується при зміні залежностей | const double = computed(() => count.value * 2) |
Усі ці механізми (render, watch, computed) - це просто різні "надбудови" над effect().
5. Effect і активний контекст
Коли виконується effect(fn):
- Vue зберігає посилання на поточний активний ефект (
activeEffect). - Усі реактивні
get-операції всерединіfnпов'язуються з цим ефектом. - Після завершення виконання
activeEffectскидається.
Завдяки цьому Vue знає, хто саме використовує дані, і кого потрібно повідомити при їх зміні.
6. Як ефекти пов'язані з компонентами
Кожен компонент у Vue має свій render effect - це функція, яка відповідає за створення/оновлення віртуального DOM.
effect(() => {
renderComponent(instance)
})Коли змінюються дані, від яких залежить шаблон,
Vue викликає саме цей effect - і компонент перемальовується.
Жодні інші компоненти не зачіпаються.
7. Чому це ефективно
Ефекти дають Vue точну гранулярність оновлень:
- Vue знає, які саме дані використовувалися.
- Vue знає, які саме ефекти залежать від цих даних.
- Vue запускає тільки потрібні ефекти.
Це робить систему:
- Швидкою
- Передбачуваною
- Масштабованою
8. Коротко і просто
Effect - це функція, яку Vue автоматично викликає при зміні будь-яких реактивних даних, які вона використовує.
9. Аналогія
Уяви effect() як формулу в Excel:
= A1 + B1Якщо змінюється A1 або B1,
таблиця автоматично перераховує формулу.
Ти не кажеш їй "перерахуй" - вона знає залежності.
effect() у Vue - це та сама формула, тільки в коді.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.