Глубокое клонирование реактивных объектов в Vue 3
3 рабочих способа
1. Комбинация
2. Ручное глубокое копирование
3. Библиотечные решения
#tip #reactivity
Vue 3
использует Proxy
для реактивности, что создает проблемы при попытке клонировать объекты. Стандартные методы работают не так, как ожидается:const state = reactive({ user: { name: "Al" } });
// Проблемы:
const badCopy1 = { ...state }; // сохраняет Proxy-ссылки
const badCopy2 = JSON.parse(JSON.stringify(state)); // теряет методы и Proxy
3 рабочих способа
1. Комбинация
toRaw
+ structuredClone
import { toRaw } from 'vue';
const original = reactive({ data: 123 });
const copy = structuredClone(toRaw(original));
2. Ручное глубокое копирование
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') return obj;
const clone = Array.isArray(obj) ? [] : {};
for (const key in obj) {
clone[key] = deepClone(obj[key]);
}
return clone;
}
const copy = reactive(deepClone(toRaw(original)));
3. Библиотечные решения
import { cloneDeep } from 'lodash-es';
const copy = reactive(cloneDeep(toRaw(obj)));
#tip #reactivity
👍11
Почему неконтролируемого использования
1. Нарушение реактивного потока
2. Плохая читаемость
Цепочки
Плохо для рефакторинга - логика, разбросанная по
3. Производительность
Неотписанные
#reactivity #watch
watch
лучше избегать?1. Нарушение реактивного потока
watch
часто скрывает логику реактивности. Например, отслеживание изменения переменной для вызова побочного эффекта (fetch
) делает поток данных менее предсказуемым, особенно если эффекты затрагивают несколько компонентов.Vue
поощряет однонаправленную реактивность (данные -> шаблон). watch
часто используется для обратной связи (данные -> данные), что усложняет отладку.2. Плохая читаемость
Цепочки
watch
внутри компонента превращаются в плохо понимаемый в спагетти-код.Плохо для рефакторинга - логика, разбросанная по
watch
, сложно переносится в composables
.3. Производительность
watch
с deep: true
может создать нагрузку при отслеживании больших объектов или массивов.watch
часто дублирует логику, которую можно выразить через computed
. Вычисляемые свойства кешируются и эффективнее.Неотписанные
watch
в динамических компонентах (например, внутри v-if
) могут накапливаться и вызывать утечки памяти.watch
— это аварийный выход для случаев, когда декларативных подходов недостаточно. Если возможно, нужно старайться решить задачу через computed
, props
или события.#reactivity #watch
👍12❤8
На vue-faq.org я написал, что
Для диаграммы на картинке я попробовал сперва построить структуру объектов на
#oop #reactivity
JS
классы во Vue
лучше не использовать. Это не совсем правильно. Не надо использовать классы с реактивными свойствами. Но если через классы создаются объекты без реактивности внутри, которые ты уже помещаешь в реактивные массивы - то вполне вариант.Для диаграммы на картинке я попробовал сперва построить структуру объектов на
TS
, получилось громоздко и запутанно. Переделал на классы - стало намного читабельней и меньше кода. Ну и типизация настоящая (почти), а не эрзац. Так что теперь это основной вариант для сложных структур данных.#oop #reactivity
🥴4✍3👍2
💩15😐4
Зачем Pinia, если можно написать свой стор?
Захотелось ответить на очень однобокий взгляд вот здесь - https://yangx.top/vuejs_ru_feed/37
Во-первых, это не велосипед, а решение под нужды своего проекта.
1. "Унификация и единый API". А давайте всех побреем и будем ходить строем. Сперва под Options API ходили, под Mixins API, под Vuex API, а теперь под Pinia API. Все, что было раньше и теперь на свалке, очевидно, было сразу плохо и временно, а вот Pinia API - это круто и навсегда, конечно
2. Нет, копию Pinia делать - это глупо. И никто это не делает. Надо решать задачи приложения, и без ограничений "единого API Pinia" они решаются проще, удобней, правильней и намного более функциональней при необходимости
3. Кроме ES модулей реализовать паттерн Singleton можно еще несколькими способами, если в этом есть необходимость по архитектуре приложения.
4. BFF SSR - зло и труп. Оставьте его врагам.
5. Какая-то надуманная проблема. Вы пишете сайты на десятки тысяч DOM элементов, а потом беспокоитесь, очистит ли GC покупательскую корзину, на которую [не] осталось ссылок?
6. А зачем очищать "глобальный стор"? Что под этим имеется ввиду, и как часто это надо делать?
Еще раз, если у тебя в реактивных переменных столько данных, что они съедают значительную часть памяти веб-приложения и тормозят его - значит ты делаешь что-то не так. Эван для этого и придумал Reactivity API, возможности которого Pinia сильно обрезает.
И, нет, память это не освободит, а пометит для GC, который вряд ли на этом сработает в большинстве случаев.
7. Почему они должны быть объединены?
9. Реклама чужих велосипедов, таких же порой неправильных, тормозных и ненужных, как и во VueUse, в попытке сделать из Vue конструктор для вкатунов
10. Такое пишут люди, которые привыкли к Pinia и к её формату. Никаких проблем в работе в DevTools с обычными ("глобальными") реактивными переменными нет.
Ну и определять архитектуру приложения на основе своих предпочтений работы в DevTools - такое.
—
У не-Pinia решений есть плюсы. Ты не ходишь строем, а ходишь, как тебе удобно, используя в полной мере Vue Reactivity API.
—
На самом деле в оригинальном посте пропущен главный пункт, такой же как с Накстом:
11 . Когда в команде много слабо квалифицированных программистов, которые могут написать дичь, удобно всем ходить строем.
Ответ:
11. Повышайте уровень своих джунов до уровня проекта, а не опускайте проект до уровня джунов.
#pinia #reactivity
Захотелось ответить на очень однобокий взгляд вот здесь - https://yangx.top/vuejs_ru_feed/37
Во-первых, это не велосипед, а решение под нужды своего проекта.
1. "Унификация и единый API". А давайте всех побреем и будем ходить строем. Сперва под Options API ходили, под Mixins API, под Vuex API, а теперь под Pinia API. Все, что было раньше и теперь на свалке, очевидно, было сразу плохо и временно, а вот Pinia API - это круто и навсегда, конечно
2. Нет, копию Pinia делать - это глупо. И никто это не делает. Надо решать задачи приложения, и без ограничений "единого API Pinia" они решаются проще, удобней, правильней и намного более функциональней при необходимости
3. Кроме ES модулей реализовать паттерн Singleton можно еще несколькими способами, если в этом есть необходимость по архитектуре приложения.
4. BFF SSR - зло и труп. Оставьте его врагам.
5. Какая-то надуманная проблема. Вы пишете сайты на десятки тысяч DOM элементов, а потом беспокоитесь, очистит ли GC покупательскую корзину, на которую [не] осталось ссылок?
6. А зачем очищать "глобальный стор"? Что под этим имеется ввиду, и как часто это надо делать?
user = null;
- это очищение стора? Свой стор не очищается при необходимости одной строчкой?Еще раз, если у тебя в реактивных переменных столько данных, что они съедают значительную часть памяти веб-приложения и тормозят его - значит ты делаешь что-то не так. Эван для этого и придумал Reactivity API, возможности которого Pinia сильно обрезает.
И, нет, память это не освободит, а пометит для GC, который вряд ли на этом сработает в большинстве случаев.
7. Почему они должны быть объединены?
9. Реклама чужих велосипедов, таких же порой неправильных, тормозных и ненужных, как и во VueUse, в попытке сделать из Vue конструктор для вкатунов
10. Такое пишут люди, которые привыкли к Pinia и к её формату. Никаких проблем в работе в DevTools с обычными ("глобальными") реактивными переменными нет.
Ну и определять архитектуру приложения на основе своих предпочтений работы в DevTools - такое.
—
У не-Pinia решений есть плюсы. Ты не ходишь строем, а ходишь, как тебе удобно, используя в полной мере Vue Reactivity API.
—
На самом деле в оригинальном посте пропущен главный пункт, такой же как с Накстом:
11 . Когда в команде много слабо квалифицированных программистов, которые могут написать дичь, удобно всем ходить строем.
Ответ:
11. Повышайте уровень своих джунов до уровня проекта, а не опускайте проект до уровня джунов.
#pinia #reactivity
Telegram
Vue Feed - Канал русскоговорящего сообщества
Зачем Pinia, если можно написать свой стор?
!store #help
Во-первых, это прежде всего велосипед - мы пишем свое собственное решение, которое делает то же самое, что и Pinia.
Во-вторых, у этого велосипеда будет масса недостатков по сравнению с готовым решением:…
!store #help
Во-первых, это прежде всего велосипед - мы пишем свое собственное решение, которое делает то же самое, что и Pinia.
Во-вторых, у этого велосипеда будет масса недостатков по сравнению с готовым решением:…
👍11👎11❤1🔥1
Невзлетевший стейт менеджер - Vaxee
С неплохими идеями и плохим маркетингом и связями
Есть какой-нибудь получивший распространение
#reactivity #pinia
С неплохими идеями и плохим маркетингом и связями
Есть какой-нибудь получивший распространение
Vue
продукт, сделанный не бандой Nuxt
-a и Ко?#reactivity #pinia
vaxee.letstri.dev
Vaxee - State Manager for Vue 3, Pinia alternative
State Manager for Vue 3 with cache, request, and more features.