Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Ререндер компонентів». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**Ререндер компонентів** у Vue визначається через реактивні ефекти: кожен компонент має свій render effect, що відстежує, які реактивні властивості він читає під час рендеру. **Ключове:** коли властивість змінюється, Vue викликає trigger() і оновлює лише ті компоненти, що від неї залежать.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Кожен компонент має свій "render effect" Коли компонент монтується, Vue створює **функцію рендера** - ту, що перетворює реактивні дані на віртуальний DOM. Ця функція огортається в **реактивний ефект (**`ReactiveEffect`**)**. ```javascript effect(() => { // render component template vnode = renderComponent() }) ``` Цей ефект працює як спостерігач: коли він викликається, Vue запам'ятовує, які реактивні властивості були "прочитані" під час рендеру. --- ## 2. Відстеження залежностей (`track`) Коли в шаблоні використовується, наприклад: ```javascript <p>{{ user.name }}</p> ``` При першому рендері відбувається таке: 1. Vue звертається до `user.name`. 2. Ця властивість - реактивна, обгорнута в `Proxy`. 3. Пастка `get` всередині Proxy викликає `track(target, key)`. 4. `track()` реєструє залежність: ```javascript targetMap = WeakMap { user -> Map { name -> Set(effectRenderComponent) } } ``` Тепер Vue **знає**, що компонент залежить від `user.name`. --- ## 3. Коли дані змінюються (`trigger`) Коли значення змінюється: ```javascript user.name = 'Alex' ``` Vue перехоплює це через пастку `set` і викликає: ```javascript trigger(user, 'name') ``` Тепер `trigger()`: 1. Знаходить усі ефекти, які залежать від `user.name` (у нашому випадку - `render effect` компонента). 2. Ставить ефект у чергу оновлення. --- ## 4. Оновлення лише потрібних компонентів У черзі може бути багато ефектів, але Vue виконує **лише ті**, що залежать від зміненої властивості. - Змінився `user.name` -> оновлюється лише компонент, де він використовується. - Змінився `count` -> оновлюється лише компонент, що використовує `count`. - Решта компонентів залишаються незмінними. Це і є **гранулярна реактивність**: Vue не робить "глобальний ререндер", а **точково** оновлює лише потрібні гілки дерева компонентів. --- ## 5. Як Vue уникає зайвих перерендерів Vue 3 робить це дуже розумно: - Компоненти мають **прапорці оновлення (dirty flags)**. - Якщо дані не змінилися (`oldValue === newValue`), перемальовування не відбувається. - Vue **батчить (batching)** оновлення: усі зміни в одному тіку об'єднуються і виконуються асинхронно в "microtask queue" (через `Promise.resolve()`). Це означає, що якщо за одну подію змінилося 10 реактивних властивостей - Vue все перерахує **один раз**, а не 10. --- ## 6. Оновлення за "реактивним деревом" Можна уявити систему залежностей як **реактивне дерево**: ```javascript Reactive data (ref, reactive) └── Computed values └── Watchers / render effects └── Components → Virtual DOM → Real DOM ``` Коли Vue викликає `trigger()`, оновлення йде **по гілці дерева**, а не по всьому застосунку. Якщо змінилася властивість `user.age`, Vue не торкнеться компонентів, що використовують `user.name`. --- ## 7. Просте пояснення людськими словами > Коли компонент рендериться, Vue "слухає", які дані він використовує. > > Потім, коли ці дані змінюються, Vue "дзвонить" лише тим компонентам, > які на них підписані. > > Все інше - не чіпає. --- ## 8. Коротке резюме | Етап | Що відбувається | |---|---| | **1. Рендер** | Компонент звертається до реактивних даних -> Vue відстежує залежності через `track()` | | **2. Зміна даних** | Proxy викликає `trigger()` для змінених властивостей | | **3. Пошук ефектів** | Vue знаходить компоненти, залежні від цих даних | | **4. Черга оновлень** | Ефекти потрапляють у чергу (batch updates) | | **5. Повторний рендер** | Перемальовуються лише потрібні компоненти | --- ## 9. Візуальна аналогія ```javascript Компонент "UserCard" ├── залежить від user.name └── залежить від user.age Компонент "PostCard" └── залежить від post.title Змінився user.name -> перемалюється лише UserCard ```Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.