Forwarded from HolyJS — канал конференции
#подкаст
Обзор State of Vue.js 2025, новый статус styled-components и обсуждение новостей JavaScript — уже через час.
Новый выпуск «Тяжелого утра» в 11:00:
— на YouTube
— в VK Видео
Обзор State of Vue.js 2025, новый статус styled-components и обсуждение новостей JavaScript — уже через час.
Новый выпуск «Тяжелого утра» в 11:00:
— на YouTube
— в VK Видео
🔥13❤4👍1
Джонсон с кем-то спорил на митапе и в процессе нашел более оптимальный алгоритм и еще большк ускорил и без того быстрый alien-signals и алгоритм вдобавок еще меньше стал весить. Все это пока нас ждет в vue3.6 однако то сколько раз за это время успели улучшить перф впечатляет
🔥17😱6👍3❤🔥2
Как внедрить MVC в мое Vue приложение?
Достаточно часто возникающий запрос в сообществе, поэтому я дам сразу на него ответ: НИКАК. Почему распишу ниже
Время идет и все развивается. Изначально MVC действительно создавался для упрощения создания интерактивных приложений... правда эта модель была опубликована в 1978(9) году. И для того момента это действительно был прогресс. Правда потом поверх MVC еще пошли MVP и MVVM (и все они живы и по сей день). Однако в мире веб-разработки пошли еще дальше и дошли до продвинутых концепций реактивности на основе сигналов.
И все же люди которые погружаются в изучения архитектуры сталкиваются с MVC и видят в нем "ну вот настоящая АРХИТЕКТУРА, если я затащу ее к себе в приложения, то у меня все будет хорошо и я буду крутым программистом". Но... так ли это? MVC в целом полностью ушло из мира UI-приложений, даже Angular с его четкими разделениями.. это скорее MVVM и то с натяжкой. На самом деле мы прошли еще один этап проектирования приложений благодаря Flux с его однонаправленным потоком данных (реакт тоже близок к этой концепции). Сам же Vue изначально описывал себя как идейно-близкое к MVVM. так вот подумайте насколько хороша затея уже имея MVVM пытаться насильно превратить его в MVC?
Я пытался пособирать информацию о том почему именно MVC не имеет смысла во Vue. но сталкивался с одним и тем же, любая попытка это дело соединить выглядит как усиленное натягивание совы на глобус и это просто не имеет смысла. У нас есть замечательная реактивная модель в рамках которой мы и должны описывать нашу бизнес логику и нет причин пытаться ее вырвать в чистые представления модели и тд. Вы можете если очень хотите ментально держать у себя в голове концептуальное MVC, но и в этом особого прока нет: у нас есть модель описываемая реактивной системой, компоненты в которые реактивная система встроена и управление которое происходит через туже реактивную модель.
Вы можете сказать, ну вот же все через реактивность и в итоге каша, а нет. У вас четко отдельное представление в виде рендера компонента. И в нем не должно быть бизнес логики и вычислений (по возможности), у вас есть скрипт который выступает как раз содержанием бизнес логики со всеми ее входами и выходами, которую можно разбивать используя композаблы, а "представление" может быть разбито на компоненты.
Кроме того у нас есть отдельные концепции глобального состояния и на нем уже тоже обжигались. Помню как повально с расцветом Flux пытались из глобального состояния сделать "единую точку истины", запихать в нее всю модель приложения, а компоненты делать тупыми насколько это возможно посредниками к глобальному состоянию и это было просто ужасно, писать было больно, а связи от этого становились только менее явными.
Поэтому прежде чем пытаться бездумно играть в Великого Архитектора, то подумайте освоили ли вы сами все методы проектирования которыми пытается наделить вас фреймворк и проанализируйте сможете ли вы реально получить какую-то выгоду от ваших "новшеств". И тем более не тащите другие подходы если вы пришли из другого фреймворка/языка просто потому что вам так привычнее (до того как опять же освоите Vue в должной мере).
В остальном я только за эксперименты, но когда только их делают осознанно и не тащат на прод не опробировав идею где-то в другом месте.
PS. Причина для данного поста и мой комментарий прикрепляю. Простите, просто уже подгорело...
Достаточно часто возникающий запрос в сообществе, поэтому я дам сразу на него ответ: НИКАК. Почему распишу ниже
Время идет и все развивается. Изначально MVC действительно создавался для упрощения создания интерактивных приложений... правда эта модель была опубликована в 1978(9) году. И для того момента это действительно был прогресс. Правда потом поверх MVC еще пошли MVP и MVVM (и все они живы и по сей день). Однако в мире веб-разработки пошли еще дальше и дошли до продвинутых концепций реактивности на основе сигналов.
И все же люди которые погружаются в изучения архитектуры сталкиваются с MVC и видят в нем "ну вот настоящая АРХИТЕКТУРА, если я затащу ее к себе в приложения, то у меня все будет хорошо и я буду крутым программистом". Но... так ли это? MVC в целом полностью ушло из мира UI-приложений, даже Angular с его четкими разделениями.. это скорее MVVM и то с натяжкой. На самом деле мы прошли еще один этап проектирования приложений благодаря Flux с его однонаправленным потоком данных (реакт тоже близок к этой концепции). Сам же Vue изначально описывал себя как идейно-близкое к MVVM. так вот подумайте насколько хороша затея уже имея MVVM пытаться насильно превратить его в MVC?
Я пытался пособирать информацию о том почему именно MVC не имеет смысла во Vue. но сталкивался с одним и тем же, любая попытка это дело соединить выглядит как усиленное натягивание совы на глобус и это просто не имеет смысла. У нас есть замечательная реактивная модель в рамках которой мы и должны описывать нашу бизнес логику и нет причин пытаться ее вырвать в чистые представления модели и тд. Вы можете если очень хотите ментально держать у себя в голове концептуальное MVC, но и в этом особого прока нет: у нас есть модель описываемая реактивной системой, компоненты в которые реактивная система встроена и управление которое происходит через туже реактивную модель.
Вы можете сказать, ну вот же все через реактивность и в итоге каша, а нет. У вас четко отдельное представление в виде рендера компонента. И в нем не должно быть бизнес логики и вычислений (по возможности), у вас есть скрипт который выступает как раз содержанием бизнес логики со всеми ее входами и выходами, которую можно разбивать используя композаблы, а "представление" может быть разбито на компоненты.
Кроме того у нас есть отдельные концепции глобального состояния и на нем уже тоже обжигались. Помню как повально с расцветом Flux пытались из глобального состояния сделать "единую точку истины", запихать в нее всю модель приложения, а компоненты делать тупыми насколько это возможно посредниками к глобальному состоянию и это было просто ужасно, писать было больно, а связи от этого становились только менее явными.
Поэтому прежде чем пытаться бездумно играть в Великого Архитектора, то подумайте освоили ли вы сами все методы проектирования которыми пытается наделить вас фреймворк и проанализируйте сможете ли вы реально получить какую-то выгоду от ваших "новшеств". И тем более не тащите другие подходы если вы пришли из другого фреймворка/языка просто потому что вам так привычнее (до того как опять же освоите Vue в должной мере).
В остальном я только за эксперименты, но когда только их делают осознанно и не тащат на прод не опробировав идею где-то в другом месте.
PS. Причина для данного поста и мой комментарий прикрепляю. Простите, просто уже подгорело...
Хабр
UI/UX: Учимся использовать настоящий MVC
Весь UI - это композиция MVC В 1972 году лаборатория Xerox PARC первой в мире изобрела компьютеры с графическим пользовательским интерфейсом (GUI). До этого момента все компьютеры управлялись через...
❤13👍5🔥3💩1💊1
createSharedComposable
Если бы меня спросили лучшие паттерны для освоения во Vue, я бы точно назвал одним из них shared composable. Почему и что это за фрукт такой?
Происхождение
Первое упоминание о shared composable было в RFC Vue посвященному Effect Scope. И там говорится о примере композабла
Как это работает?
На самом деле весьма не хитрым образом. Оно использует API Effect Scope + счетчик подписчиков, когда подписчиков становится 0 он уничтожает текущий скоуп. Вот и все. А... возможно вам не совсем знакомо что же такое Effect Scope (однажды мой доклад на эту тему уже выложат на YouTube...). А вот поэтому этот паттерн и хорош, он заставляет вас слегка заглянуть поглубже в работу Vue. Я уже приложил ссылку на RFC, где крайне подробно расписано что такое реактивные скоупы и как они работают. Если совсем сократить и упростить, то эффект скоупы это как мешок для реактивности: он запоминает все вызванные
А чем же так крут этот паттерн еще?
1. Учебный эффект позволяющий лучше понять работу Vue
2. Возможность оптимизации как в примере c
3. Он позволяет на SPA приложениях спокойно заменить Pinia или другой STM на себя, так как спокойно выполняет обязанности глобального стейт менеджера, только еще и умеет уничтожаться когда никому не нужен (с pinia я видел как люди вручную это дело пытаются зачищать)
4. Advanced DI. По сути созданный композабл это сервис который может жить внутри
А какие есть минусы?
- Это не самое SSR Friendly решение
- Этого API нет из коробки, поэтому вам придется либо писать его самим, либо взять из vueuse
- Можно при неаккуратном использовании натворить страшных вещей
- Алгоритм использует простой счетчик, поэтому циклическая зависимость приведет к невозможности уничтожения (если не создать ручной "рубильник")
Итого: классный паттерн имеющий крайне широкие возможности с дополнительным эффектом погружения в мир реактивности Vue, однозначно рекомендую к изучению
Если бы меня спросили лучшие паттерны для освоения во Vue, я бы точно назвал одним из них shared composable. Почему и что это за фрукт такой?
Происхождение
Первое упоминание о shared composable было в RFC Vue посвященному Effect Scope. И там говорится о примере композабла
useMouse
который слушает перемещения мышки и возвращает это в виде реактивных переменных координат. И вроде логично, что это не самое легковесное действие. А если это нужно множеству компонентов? Да каждый компонент использующий useMouse
подписывается на него и это становится уже ощутимо. Тогда почему бы просто не вынести в глобальный STM как Pinia? Отличный вариант, но он будет работать даже когда нет никого кому нужны эти данные. И вот тут на помощь приходит shared composable он умеет как STM шарить данные на множество инстансов, но при этом если никто его не использует, то "стор" уничтожается! При этом сам паттерн универсальный и все что вам нужно это обернуть обычный композабл в createSharedComposable
. И да, как только все компоненты использующие useMouse
будут размонтированы shared composable тоже отпишется от событий мышки.Как это работает?
На самом деле весьма не хитрым образом. Оно использует API Effect Scope + счетчик подписчиков, когда подписчиков становится 0 он уничтожает текущий скоуп. Вот и все. А... возможно вам не совсем знакомо что же такое Effect Scope (однажды мой доклад на эту тему уже выложат на YouTube...). А вот поэтому этот паттерн и хорош, он заставляет вас слегка заглянуть поглубже в работу Vue. Я уже приложил ссылку на RFC, где крайне подробно расписано что такое реактивные скоупы и как они работают. Если совсем сократить и упростить, то эффект скоупы это как мешок для реактивности: он запоминает все вызванные
watcher
-ы и уничтожает их в нужный момент (да-да именно так работает setup
в компонентах). А вместо onUnmounted
вы можете использовать onScopeDispose
.А чем же так крут этот паттерн еще?
1. Учебный эффект позволяющий лучше понять работу Vue
2. Возможность оптимизации как в примере c
useMouse
3. Он позволяет на SPA приложениях спокойно заменить Pinia или другой STM на себя, так как спокойно выполняет обязанности глобального стейт менеджера, только еще и умеет уничтожаться когда никому не нужен (с pinia я видел как люди вручную это дело пытаются зачищать)
4. Advanced DI. По сути созданный композабл это сервис который может жить внутри
provide
/ inject
и расшаривать данные и логику как STM, но только на определенной части приложения (я не раз видело как пытаются генерировать это с pinia + id стора
)А какие есть минусы?
- Это не самое SSR Friendly решение
- Этого API нет из коробки, поэтому вам придется либо писать его самим, либо взять из vueuse
- Можно при неаккуратном использовании натворить страшных вещей
- Алгоритм использует простой счетчик, поэтому циклическая зависимость приведет к невозможности уничтожения (если не создать ручной "рубильник")
Итого: классный паттерн имеющий крайне широкие возможности с дополнительным эффектом погружения в мир реактивности Vue, однозначно рекомендую к изучению
🔥31❤5
Provide/inject.
Часть 1: Основы использования
Сегодня затронем тему с которой чаще всего ко мне подходили люди с удивлением: как так, ты призываешь использовать
Но для начала я должен успокоить тех, кто пришел из Vue2 и все еще боится использовать столь мощный механизм во Vue3:
1. Прекрасно типизируется
2. Дружит с реактивностью замечательно (хотя конечно есть способы сломать ее)
3. Имеет в подспорье композаблы, а не миксины для удобной работы с ними
4. За счет изоляции внутри компонента менее магический (речь о том что ты не можешь инжектить себе в этот же компонент что ты запровайдил)
5. Вместо строк нам доступны ключи-символы, что снимает вероятность получения коллизий
Отлично, теперь когда мы разобрались с тем почему миксины во Vue2 и Vue3 совершенно на разных уровнях. я даю список рекомендаций по использованию:
1. Использовать TypeScript (да-да это тот самый способ добиться корректной типизации provide/inject)
2. Всегда использовать ключи символы
- так как это убережет вас от возможных коллизий
- Повысит изоляцию, так как без доступа к символу никто не сможет считать значение
- Дает возможность использовать типизацию в полной мере
3. Всегда использовать ТОЛЬКО внутри композаблов
- прячем такие кишки под капот
- ограничиваем API для взаимодействия с нашим контекстом, теперь в композабле вы определяете как можно пользоваться вашим
- это уберет необходимость экспортировать символ (держите его всегда "в секрете")
- вы сможете в нем обработать любые ситуации (например как поступить если такого ключа нет?)
4. Делайте раздельные композаблы по мере необходимости. Например разделение на того кто может провайдить данные и композабл для тех кто его инжектит
- вновь позволит сохранить вам удобное API
- это безопасно и не вызовет каши в вызовах
На самом деле тема крайне обширная и в 1 пост ее не уместить, но эти несложные 4 правила уже превратят страшный
Следующие темы:
- Где и когда использовать?
- Продвинутое использование
- Полноценное DI на provide/inject
PS. попробую ввести теги для вашего удобства
#di #my #learn
Часть 1: Основы использования
Сегодня затронем тему с которой чаще всего ко мне подходили люди с удивлением: как так, ты призываешь использовать
provide/inject
это же кошмар. Далее следует обсуждение в котором выясняется, что у человека табу на provide/inject появилось в момент еще изучения Vue2 или изучения Vue по материалам актуальным для Vue2. Также я не совсем согласен с некоторыми рекомендациями в документации, они хороши, но только когда мы используем provide/inject
сами по себе, вне контекста моих советов.Но для начала я должен успокоить тех, кто пришел из Vue2 и все еще боится использовать столь мощный механизм во Vue3:
1. Прекрасно типизируется
2. Дружит с реактивностью замечательно (хотя конечно есть способы сломать ее)
3. Имеет в подспорье композаблы, а не миксины для удобной работы с ними
4. За счет изоляции внутри компонента менее магический (речь о том что ты не можешь инжектить себе в этот же компонент что ты запровайдил)
5. Вместо строк нам доступны ключи-символы, что снимает вероятность получения коллизий
Отлично, теперь когда мы разобрались с тем почему миксины во Vue2 и Vue3 совершенно на разных уровнях. я даю список рекомендаций по использованию:
1. Использовать TypeScript (да-да это тот самый способ добиться корректной типизации provide/inject)
2. Всегда использовать ключи символы
- так как это убережет вас от возможных коллизий
- Повысит изоляцию, так как без доступа к символу никто не сможет считать значение
- Дает возможность использовать типизацию в полной мере
3. Всегда использовать ТОЛЬКО внутри композаблов
- прячем такие кишки под капот
- ограничиваем API для взаимодействия с нашим контекстом, теперь в композабле вы определяете как можно пользоваться вашим
provide/inject
, а не "бросаем что-то куда-то пусть используют"- это уберет необходимость экспортировать символ (держите его всегда "в секрете")
- вы сможете в нем обработать любые ситуации (например как поступить если такого ключа нет?)
4. Делайте раздельные композаблы по мере необходимости. Например разделение на того кто может провайдить данные и композабл для тех кто его инжектит
- вновь позволит сохранить вам удобное API
- это безопасно и не вызовет каши в вызовах
На самом деле тема крайне обширная и в 1 пост ее не уместить, но эти несложные 4 правила уже превратят страшный
provide/inject
в одного из лучших друзей, сохранят предсказуемость и прозрачность в вашем приложении.Следующие темы:
- Где и когда использовать?
- Продвинутое использование
- Полноценное DI на provide/inject
PS. попробую ввести теги для вашего удобства
#di #my #learn
vuejs.org
Vue.js
Vue.js - The Progressive JavaScript Framework
👍32❤7🔥6🍌1👀1
Provide/inject.
Часть 2: Где и когда использовать?
В прошлой части мы рассмотрели рекомендации по использованию provide/inject (давайте для краткости будем называть это контекстом, так как это наименование используется в большинстве фреймворков). И так, где же будет уместно использование контекста.
Для начала я бы рассмотрел природу этого механизма, чтобы делать какие-то выводы:
1. Оно сквозное - самый принцип который узнают все пользователи, что это способ избежать необходимости прокидывать пропсы, чтобы доносить его до низлежащих компонентов, что роднит его с глобальным стейтом, который тоже доступен ото всюду
2. Оно иерархическое - а вот это наиболее интересный и важный пункт. Это свойство позволяет от любого компонента строить иерархию контекстов на всю глубину/до переопределения. Это роднит его с пропсами, когда каждый компонент имеет свой стейт, только тут поддерево
Таким образом оно позволяет нам что-то синхронизировать на всей протяженности поддерева на котором оно определено. Где бывает такое нужно:
1. Компоненты с четкой иерархией. Например
2. Работа плагинов и прочие глобальные "неявное API". Вот вы используете Pinia / Vuex / VueRouter и тд. А как вообще они узнают информацию о роутере и так далее, они на самом деле они прокидывают контекст в корень приложения и далее вам не нужно переживать как они это используют, они просто достанут из контекста всю информацию для работы API. Поэтому если вам нужно универсальное API, без глобального стора(например потому что вы пишите внутренний плагин или возможно множество инстансов), то это отличный вариант.
3. Сервисы ограниченные поддеревом. Наиболее интересная и при этом наиболее неразвитое направление в использовании. Это буквально наиболее активно используемый механизм в ангуляре, на его основе работает продвинутое DI и так далее. Что это такое? Вот обычно мы логику с данными которая может использоваться несколькими компонентами в глобальный стор, а что делать если это нужно нам лишь в определенной части приложения или нам вообще нужно множество таких инстансов запустить? Тут идут как раз трюки с добавлением
4. API важное лишь на определенных страницах. Это по факту 3ий пункт, но более специализированный. По сути это призыв не пихать все подряд в глобальный стор, на то он и глобальный, что должен иметь смысл ВЕЗДЕ. А если он несет смысл лишь на конкретных страницах, то это API этих страниц и лучшим решением будет запуска сервиса на этих страницах и прокидыванием его в контекст и взаимодействиями через него же. Таким образом можно сохранять ваш стм чистым от специфичной логики и держать специфичные сервисы ближе к месту их использования (особенно если вы используете модульную архитектуру проекта)
Таким образом мы обрисовали основные причины для использования provide/inject во Vue приложениях
#di #my #learn
Часть 2: Где и когда использовать?
В прошлой части мы рассмотрели рекомендации по использованию provide/inject (давайте для краткости будем называть это контекстом, так как это наименование используется в большинстве фреймворков). И так, где же будет уместно использование контекста.
Для начала я бы рассмотрел природу этого механизма, чтобы делать какие-то выводы:
1. Оно сквозное - самый принцип который узнают все пользователи, что это способ избежать необходимости прокидывать пропсы, чтобы доносить его до низлежащих компонентов, что роднит его с глобальным стейтом, который тоже доступен ото всюду
2. Оно иерархическое - а вот это наиболее интересный и важный пункт. Это свойство позволяет от любого компонента строить иерархию контекстов на всю глубину/до переопределения. Это роднит его с пропсами, когда каждый компонент имеет свой стейт, только тут поддерево
Таким образом оно позволяет нам что-то синхронизировать на всей протяженности поддерева на котором оно определено. Где бывает такое нужно:
1. Компоненты с четкой иерархией. Например
Tabs
и Tab
. В этом случае очевидно, что Tab
без Tabs
не имеет смысла и одно вложено в другое, а Tabs
может отправлять необходимые данные или использование данные от Tab
через контекст. Еще примеры таких компонентов: RadioGroup
+Radio
/ Form
+inputs
. На самом деле современные headless ui библиотеки буквально полностью построены на таких иерархиях и иногда эти особенности называют "анатомией компонента", те какие компоненты во что могут быть вложены и из чего состоят. Поэтому если вам нужно создать компонент который работает в паре с другим компонентом, то это нормально завести для их взаимодействия контекст.2. Работа плагинов и прочие глобальные "неявное API". Вот вы используете Pinia / Vuex / VueRouter и тд. А как вообще они узнают информацию о роутере и так далее, они на самом деле они прокидывают контекст в корень приложения и далее вам не нужно переживать как они это используют, они просто достанут из контекста всю информацию для работы API. Поэтому если вам нужно универсальное API, без глобального стора(например потому что вы пишите внутренний плагин или возможно множество инстансов), то это отличный вариант.
3. Сервисы ограниченные поддеревом. Наиболее интересная и при этом наиболее неразвитое направление в использовании. Это буквально наиболее активно используемый механизм в ангуляре, на его основе работает продвинутое DI и так далее. Что это такое? Вот обычно мы логику с данными которая может использоваться несколькими компонентами в глобальный стор, а что делать если это нужно нам лишь в определенной части приложения или нам вообще нужно множество таких инстансов запустить? Тут идут как раз трюки с добавлением
id
к именам сторов в Pinia и прочие трюки по "размножению" STM, а по факту раз это имеет смысл лишь в определенном поддереве приложения, то именно этот механизм наиболее аккуратно может быть взят для использования. Таким образом можно даже включать различные цветовые темы в разных подчастях приложения. 4. API важное лишь на определенных страницах. Это по факту 3ий пункт, но более специализированный. По сути это призыв не пихать все подряд в глобальный стор, на то он и глобальный, что должен иметь смысл ВЕЗДЕ. А если он несет смысл лишь на конкретных страницах, то это API этих страниц и лучшим решением будет запуска сервиса на этих страницах и прокидыванием его в контекст и взаимодействиями через него же. Таким образом можно сохранять ваш стм чистым от специфичной логики и держать специфичные сервисы ближе к месту их использования (особенно если вы используете модульную архитектуру проекта)
Таким образом мы обрисовали основные причины для использования provide/inject во Vue приложениях
#di #my #learn
🔥27🍌2
Provide/inject.
Часть 2.1: Когда НЕ НАДО использовать?
Мы разобрались с основными мотивациями для использования. Теперь разберемся, когда использование
1. Пункт специально предназначенный для реактеров. НЕ НАДО использовать контексты как глобальное хранилище и пихать в них все, что нужно глобально. Для этого есть множество других способов (да даже переменные на уровне модулей). Конечно, у вас будет работать все как и задумано, но вам не захочется использовать это таким способом (если вы прочли 1 часть), так как это будет крайне избыточно, да и профитов вы от этого не получите.
2. Контексты это не замена пропсам/ивентам, это принципиально другой механизм, это скорее способ установления множественных связей те когда МНОЖЕСТВУ компонентов в поддереве нужна связь с ОДНИМ компонентом родителя, а не 1 к 1(в случае плагинов можно считать что это связь ПРИЛОЖЕНИЯ и компонентов использующих API плагина). И у данных соединенных контекстом должна быть четкая цель для этого, а не просто экономия на создании пропсов. Стоит задуматься о "уходе от пропс дриллинга", если вам приходится заводить пропсы которые не имеют никакого смысла для промежуточных компонентов, кроме как быть прокинутыми еще дальше, в этом случае подумать о переходе на контексты можно, так как это значит, что вам необходима именно сквозная связь компонентов.
3. Не бросайте в контексты все подряд. Очевидное, но важное пояснение. Старайтесь удерживать количество контекстов минимально необходимым. Так как мутации в контекстах менее явные и не логгируются девтулзами, то лучше этот объем снижать, чтобы не превратить вашу кодовую базу в клубок из мутаций. Опять же, вам тут поможет четкое разделение по композаблам и использование контекстов только через них. Те если у вас есть ПРОСТАЯ возможность не использовать
Я надеюсь, что мне удалось донести, когда стоит использовать
#di #my #learn
Часть 2.1: Когда НЕ НАДО использовать?
Мы разобрались с основными мотивациями для использования. Теперь разберемся, когда использование
provide/inject
либо не имеет смысла, либо будет вредоносно.1. Пункт специально предназначенный для реактеров. НЕ НАДО использовать контексты как глобальное хранилище и пихать в них все, что нужно глобально. Для этого есть множество других способов (да даже переменные на уровне модулей). Конечно, у вас будет работать все как и задумано, но вам не захочется использовать это таким способом (если вы прочли 1 часть), так как это будет крайне избыточно, да и профитов вы от этого не получите.
2. Контексты это не замена пропсам/ивентам, это принципиально другой механизм, это скорее способ установления множественных связей те когда МНОЖЕСТВУ компонентов в поддереве нужна связь с ОДНИМ компонентом родителя, а не 1 к 1(в случае плагинов можно считать что это связь ПРИЛОЖЕНИЯ и компонентов использующих API плагина). И у данных соединенных контекстом должна быть четкая цель для этого, а не просто экономия на создании пропсов. Стоит задуматься о "уходе от пропс дриллинга", если вам приходится заводить пропсы которые не имеют никакого смысла для промежуточных компонентов, кроме как быть прокинутыми еще дальше, в этом случае подумать о переходе на контексты можно, так как это значит, что вам необходима именно сквозная связь компонентов.
3. Не бросайте в контексты все подряд. Очевидное, но важное пояснение. Старайтесь удерживать количество контекстов минимально необходимым. Так как мутации в контекстах менее явные и не логгируются девтулзами, то лучше этот объем снижать, чтобы не превратить вашу кодовую базу в клубок из мутаций. Опять же, вам тут поможет четкое разделение по композаблам и использование контекстов только через них. Те если у вас есть ПРОСТАЯ возможность не использовать
provide/inject
НЕ ИСПОЛЬЗУЙТЕ ИХ. Но и не демонизируйте избегая контексты любыми путями. Например модульная переменная с точки зрения прозрачности использования не особо лучше помогает понять кто ее мутирует, а вот пропсы/ивенты делают это более явным. Но и 3 уровня бессмысленного прокидывания пропсов до целевого компонента сильно лучше ситуацию не сделают. Однако тут у меня нет для вас однозначного рецепта, сколько уровней и когда дают смысл к использованию, все-таки построение архитектуры во многом основывается на опыте и вкусе разработчика, а не четкая блок схема когда и что использоватьЯ надеюсь, что мне удалось донести, когда стоит использовать
provide/inject
. Если же у вас все еще остались вопросы, то буду рад на них ответить.#di #my #learn
🔥20❤1💯1
В чате закинули интересную тему. 2 подхода к извлечению данных о текущем роуте: Props vs Composables
1. Composables
Это доступ к значению напрямую через API роутов
Тут мы достаем из id указанный в URL (также можем брать метаданные и тд)
2. Props
Но нам из коробки доступен более "нативный способ" получения параметров в компоненте-странице:
Да, данный способ доступен лишь в компоненте непосредственно являющимся корневым для страницы, но вы можете дальше использовать его по вашему усмотрению (например настроить сервисы/сторы для работы с этим id). Также в настройках роута можно тонко настроить что и как будет лететь в пропсы компонента
И как часто бывает, то однозначного ответа как лучше использовать - нет.
Вариант с композаблом будет работать везде, его можно обернуть в свой композабл для работы с роутами и прочими API, а вариант через пропсы смотрится приятнее и менее перегруженный.
Поэтому у меня тут не столько пост, сколько опрос, а что предпочитаете вы?
#router #poll
1. Composables
Это доступ к значению напрямую через API роутов
const route = useRoute()
const currentProductId = computed(() => route.params.id)
Тут мы достаем из id указанный в URL (также можем брать метаданные и тд)
2. Props
Но нам из коробки доступен более "нативный способ" получения параметров в компоненте-странице:
const id = defineProps<{
id: String
}>()
Да, данный способ доступен лишь в компоненте непосредственно являющимся корневым для страницы, но вы можете дальше использовать его по вашему усмотрению (например настроить сервисы/сторы для работы с этим id). Также в настройках роута можно тонко настроить что и как будет лететь в пропсы компонента
// /search?q=Hello
const routes = [
{
path: '/search',
component: SearchUser,
props: route => ({ query: route.query.q }
}
]
И как часто бывает, то однозначного ответа как лучше использовать - нет.
Вариант с композаблом будет работать везде, его можно обернуть в свой композабл для работы с роутами и прочими API, а вариант через пропсы смотрится приятнее и менее перегруженный.
Поэтому у меня тут не столько пост, сколько опрос, а что предпочитаете вы?
#router #poll
router.vuejs.org
Vue Router
The official Router for Vue.js
🔥10🥴5
Forwarded from zede code
Дождался. Доклад по Шестеренкам реактивности Vue наконец-то вышел. В нем были разобраны базовые механизмы на которых основана работа реактивности во Vue.
- Ссылка на презентацию
- Ссылка на карту реактивности
И так полезный сопровождающий материал:
- Chibivue [Ru]
- Курс от Michael Thiessen
- Ссылка на презентацию
- Ссылка на карту реактивности
И так полезный сопровождающий материал:
- Chibivue [Ru]
- Курс от Michael Thiessen
YouTube
Денис Чернов — Шестеренки реактивности Vue
Подробнее о конференции HolyJS: https://jrg.su/EM4wwV
— —
Мы любим Vue за простоту и скорость разработки на нем. Но часто говорят, что в нем много магии и подкапотной работы. Однако ощущение магии развеивается, если разобраться, как работают все шестеренки…
— —
Мы любим Vue за простоту и скорость разработки на нем. Но часто говорят, что в нем много магии и подкапотной работы. Однако ощущение магии развеивается, если разобраться, как работают все шестеренки…
🔥41🎉3🍌3❤2✍1
И вот в полку инструментов которые уже используют Rolldown прибыло. Надеемся на скорейший релиз vite+rolldown.
Только что на него переехал vue-create(раньше был на esbuild). В остальном релиз скорее связан с улучшением дефолтного конфига ESLint
#rolldown #release
Только что на него переехал vue-create(раньше был на esbuild). В остальном релиз скорее связан с улучшением дефолтного конфига ESLint
#rolldown #release
🔥10👍1
Provide/inject
Часть 3: Используем API на практике
Во Vue у нас есть Suspense, но он уже кучу лет висит в Experimental, да и не нужен он особо сейчас во Vue в текущем виде (данное обсуждение я бы вынес в отдельный пост). Однако, что нам делать если мы хотим определять лоадеры в родителе, а дети подгружали бы данные и не парились насчет кто и как показывает лоадер и это вместо того, чтобы делать парады спиннеров (когда каждый компонент имеет свой лоадер) или 1 глобальный лоадер перекрывающий все приложение. Вот с таким запросом заходили в чате.
И решение достаточно простое:
1. Пусть компонент который может показывать лоадер запровайдит API ниже через
2. Дочерний компонент через API сможет его подгрузить через
3. Соответственно родитель может знать о всех загрузках и показывать Loader когда необходимо
Однако у этого решения есть 2 специфичных минуса
- При первом рендере родителя он еще не знает будут ли грузиться дети (можем первый рендер вообще ничего не рендерить как пример)
- Мы не можем показывать loader / дети по условному v-if и нам нужно думать, как их отображать (например через v-show)
И вот получается базовая реализация. Изучите ее пожалуйста, так как в ней использованы все советы из прошлых постов.
Однако, как поведет такая реализация себя если компонент с лоадером мы вложим в компонент с лоадером? Сейчас каждый компонент с лоадером порождает независимый лоадер: то есть лоадер выше не знает о загрузках которые идут от лоадера ниже. И иногда данное поведение нас устраивает, а что если мы хотим, чтобы наш компонент показывал Loader даже, когда грузятся внутренние лоадеры? В этом случае мы могли бы просто не использовать
Теперь мы имеем достаточное простое и лаконичное API для работы с лоадерами на проекте при этом обладая полной гибкостью в работе с ними. И такой подход было бы крайне затруднительно реализовать без механизма provide/inject
#di #my #learn #example
Часть 3: Используем API на практике
Во Vue у нас есть Suspense, но он уже кучу лет висит в Experimental, да и не нужен он особо сейчас во Vue в текущем виде (данное обсуждение я бы вынес в отдельный пост). Однако, что нам делать если мы хотим определять лоадеры в родителе, а дети подгружали бы данные и не парились насчет кто и как показывает лоадер и это вместо того, чтобы делать парады спиннеров (когда каждый компонент имеет свой лоадер) или 1 глобальный лоадер перекрывающий все приложение. Вот с таким запросом заходили в чате.
И решение достаточно простое:
1. Пусть компонент который может показывать лоадер запровайдит API ниже через
useLoaderProvider
2. Дочерний компонент через API сможет его подгрузить через
useLoader
и достать оттуда функцию wait
, которая принимает Promise и сообщает родителю, что мы грузим какие-то дочерние данные3. Соответственно родитель может знать о всех загрузках и показывать Loader когда необходимо
Однако у этого решения есть 2 специфичных минуса
- При первом рендере родителя он еще не знает будут ли грузиться дети (можем первый рендер вообще ничего не рендерить как пример)
- Мы не можем показывать loader / дети по условному v-if и нам нужно думать, как их отображать (например через v-show)
И вот получается базовая реализация. Изучите ее пожалуйста, так как в ней использованы все советы из прошлых постов.
Однако, как поведет такая реализация себя если компонент с лоадером мы вложим в компонент с лоадером? Сейчас каждый компонент с лоадером порождает независимый лоадер: то есть лоадер выше не знает о загрузках которые идут от лоадера ниже. И иногда данное поведение нас устраивает, а что если мы хотим, чтобы наш компонент показывал Loader даже, когда грузятся внутренние лоадеры? В этом случае мы могли бы просто не использовать
provide
во внутреннем лоадере, если он увидит уже запровайженное значение. Таким образом получаем улучшенный пример.Теперь мы имеем достаточное простое и лаконичное API для работы с лоадерами на проекте при этом обладая полной гибкостью в работе с ними. И такой подход было бы крайне затруднительно реализовать без механизма provide/inject
#di #my #learn #example
🔥21👍6🤨2
Наглядный key
Этот пост больше направлен для начинающих, которым нужно разобраться в концепции
1. Это классический-правильный: мы ставим индекс по уникальному ID квадрата. Мы можем заметить, что квадраты при обновлении корректно перемещаются, а при пересоздании заменяются на новые, также корректно ведут себя при добавлении в начало и конец списка
2. Это вариант без установки
3. Вариант с ключом по индексу - по факту почти тоже самое, что без индекса
4. Вариант с рандомным key - ну тут полный треш, на любое действия элементы пересоздают и никаких анимаций вообще нет.
Итого: 1ый вариант нужно использовать по возможности.3ий вариант более предпочтителен чем второй, так как он явно показывает ваше намерение, однако применять его стоит лишь, когда вы уверены в статичности элементов списка (всегда конкретное количество) или идет добавление всегда только в конец
Поиграйтесь и поизучайте пример (на самом деле там достаточно интересных техник использовано, например новые cqw/cqh единицы измерения в CSS). И вам станет кристально понятно что и зачем нужен
Небольшое дополнение о механике работы key. Key это не просто "помочь vue рендерить оптимизировано" или подобные ответы, а это буквально способ дать id нашим элементам и дать возможность vue корректно реагировать на их изменения/перемещения. Также если вы используете key вне списков, то это способ форсированно пересоздавать компоненты (соответственно при смене key произойдет полный цикл с размонтированием старого элемента и монтированием нового, а не просто "форсированный апдейт")
Этот пост больше направлен для начинающих, которым нужно разобраться в концепции
key
во Vue. И сделаю я это через вот этот пример. В нем я реализовал 4 основных "способа" установки ключей в списках.1. Это классический-правильный: мы ставим индекс по уникальному ID квадрата. Мы можем заметить, что квадраты при обновлении корректно перемещаются, а при пересоздании заменяются на новые, также корректно ведут себя при добавлении в начало и конец списка
2. Это вариант без установки
key
вообще. Мы видим, что квадраты корректно обновляются, но если квадраты пересоздать, то они посчитают это тоже обновлением и переместятся (те ноды останутся прежними), в случае добавления в нового элемента в конец - все корректно, в случае добавления в начало, то элементы змейкой передвинутся к месту ранее более высокого индекса3. Вариант с ключом по индексу - по факту почти тоже самое, что без индекса
4. Вариант с рандомным key - ну тут полный треш, на любое действия элементы пересоздают и никаких анимаций вообще нет.
Итого: 1ый вариант нужно использовать по возможности.3ий вариант более предпочтителен чем второй, так как он явно показывает ваше намерение, однако применять его стоит лишь, когда вы уверены в статичности элементов списка (всегда конкретное количество) или идет добавление всегда только в конец
Поиграйтесь и поизучайте пример (на самом деле там достаточно интересных техник использовано, например новые cqw/cqh единицы измерения в CSS). И вам станет кристально понятно что и зачем нужен
key
Небольшое дополнение о механике работы key. Key это не просто "помочь vue рендерить оптимизировано" или подобные ответы, а это буквально способ дать id нашим элементам и дать возможность vue корректно реагировать на их изменения/перемещения. Также если вы используете key вне списков, то это способ форсированно пересоздавать компоненты (соответственно при смене key произойдет полный цикл с размонтированием старого элемента и монтированием нового, а не просто "форсированный апдейт")
🔥17👍8❤5🤔1🤨1
У нашего друга Володи(вы его можете знать как Душный Вуй) поганый телеграм каким-то образом снес канал (он просто исчез в момент и все, поддержка молчит)
Володя вел интересный авторский канал посвященный разработке на Vue
Но Володя не растерялся и создал новый (он перенес старые посты, но комменты к ним не привязаны)
Давайте поможем восстановить подписчиков
Просим дружественные нам сообщества сделать репост
https://t.iss.one/stuffy_vuejs
Володя вел интересный авторский канал посвященный разработке на Vue
Но Володя не растерялся и создал новый (он перенес старые посты, но комменты к ним не привязаны)
Давайте поможем восстановить подписчиков
Просим дружественные нам сообщества сделать репост
https://t.iss.one/stuffy_vuejs
Telegram
Душный Вуй
Немного душные, но ламповые заметки о Vue.js
#vuejs #vue #nuxt #vuex #pinia #вью #vapor
#vuejs #vue #nuxt #vuex #pinia #вью #vapor
❤19🤯1
Всем привет. Меня не было какое-то время (2 недели), да был отпуск, но фактически было путешествие по конференциям и теперь я готов продолжать писать новые посты (во время поездки это было слишком затруднительно).
А сейчас некоторые моменты:
1) Был на конференции Holy.js, где был членом ПК и экспертом, как всегда получил невероятный заряд от ребят. Также там была команда Msk Vue.js(+ с ними был уже знакомый нам Душный Вуй) с которыми я также активно взаимодействовал. кроме этого в день конференции удалось накидать мини-доклад на открытый микрофон о Vue. Я очень надеюсь, что мини-доклад смогу развить в полноценный и реализовать его уже серьезно.
2) Был на конференции Go Cloud от cloud.ru. Там я уже был чисто гостем, но просто посетить мероприятие было бы слишком скучно, поэтому с ребятам из сообщества IT-хохяев (в том числе Siberia can code) делали стрим прямо с конференции и побыли в роли "репортеров". Встретили людей совершенно разных направлений и просили их рассказать о своей работе
3) Был на подкасте от cloud.ru, где записали подкаст о Vue и влиянии AI. Много чего не рассказали из того что хотелось из-за тайимнгов, в остальном все прошло супер.
4) Был на Стачка в роли Эксперта секции Frontend. Тоже 3 дня в Ульяновске прошли сумасшедше. На доступном мне уровне как мог просвещал в промежутках о Vue.js и его преимуществах
5) Записали подкаст Тяжелое Утро (в нем вкраплений про Vue было минимум (( )
И на самом деле это не совсем конец. Так как я уже приступил к написанию доклада к ребятам из Msk Vue.js, думаю совсем скоро они сделают анонс и расскажут о предстоящем мероприятии. Кроме этого хочется придумать доклад для уже следующего сезона Holy.js по Vue.js и тут мне нужна ваша помощь, накидайте идей в комментариях о чем бы хотели услышать на этом докладе.
PS. Если же у вас уже есть идеи и вы хотите выступить сами, то форма подачи заявки Holy.js уже работает. По любым вопросам связанным с подачей и помощью с подготовкой докладов можете трясти меня в ЛС и комментариях
#личное
А сейчас некоторые моменты:
1) Был на конференции Holy.js, где был членом ПК и экспертом, как всегда получил невероятный заряд от ребят. Также там была команда Msk Vue.js(+ с ними был уже знакомый нам Душный Вуй) с которыми я также активно взаимодействовал. кроме этого в день конференции удалось накидать мини-доклад на открытый микрофон о Vue. Я очень надеюсь, что мини-доклад смогу развить в полноценный и реализовать его уже серьезно.
2) Был на конференции Go Cloud от cloud.ru. Там я уже был чисто гостем, но просто посетить мероприятие было бы слишком скучно, поэтому с ребятам из сообщества IT-хохяев (в том числе Siberia can code) делали стрим прямо с конференции и побыли в роли "репортеров". Встретили людей совершенно разных направлений и просили их рассказать о своей работе
3) Был на подкасте от cloud.ru, где записали подкаст о Vue и влиянии AI. Много чего не рассказали из того что хотелось из-за тайимнгов, в остальном все прошло супер.
4) Был на Стачка в роли Эксперта секции Frontend. Тоже 3 дня в Ульяновске прошли сумасшедше. На доступном мне уровне как мог просвещал в промежутках о Vue.js и его преимуществах
5) Записали подкаст Тяжелое Утро (в нем вкраплений про Vue было минимум (( )
И на самом деле это не совсем конец. Так как я уже приступил к написанию доклада к ребятам из Msk Vue.js, думаю совсем скоро они сделают анонс и расскажут о предстоящем мероприятии. Кроме этого хочется придумать доклад для уже следующего сезона Holy.js по Vue.js и тут мне нужна ваша помощь, накидайте идей в комментариях о чем бы хотели услышать на этом докладе.
PS. Если же у вас уже есть идеи и вы хотите выступить сами, то форма подачи заявки Holy.js уже работает. По любым вопросам связанным с подачей и помощью с подготовкой докладов можете трясти меня в ЛС и комментариях
#личное
Telegram
MSK VUE.JS
Публичный чат сообщества разработчиков MSK VUE.JS.
CFP https://forms.gle/R3mViSS2SPWtfcHV8
CFP https://forms.gle/R3mViSS2SPWtfcHV8
🔥13❤4
@click="router.push('/hell')"
Так, потихоньку возвращаемся к регулярным постам. И сегодня у меня небольшая напоминалка: если это возможно, то всегда предпочитайте нормальную ссылку вместо
router.push
.Ведь одно из самых бесящих вещей на сайтах, когда ты хочешь что-то открыть в новой вкладке, а тебе не дают и нет никаких причин по которой это было сделано. А уж о доступности в таком подходе и говорить не приходится.
еще раз. если видите что-то подобное
@click="router.push('/smth')"
То приложите усилия, чтобы это стало
<RouterLink>
-ом или на крайний случай <a>
, таким образом вы сделаете мир чуточку но лучше (и никто не захочет вам пожелать отдельного котла)#remainder #learn #ux
👍47💯13🥰3❤2🫡1
Forwarded from MSK VUE.JS News
Всем привет 🙂
Это мы идем с крутыми новостями🤪
Алярм: мы открываем регистрацию на новый митап!
📆 29 мая 2025, 19:00
📍 Мск, Крылатская 15, Офис Lamoda
👉 РЕГИСТРАЦИЯ👈
В 13-ый раз команда сообщества MskVue.js соберет единомышленников в офисе Lamoda!
Вас ждут 3 доклада, розыгрыш мерча за лучший вопрос спикеру и просто тонна общения с крутыми разрабами 🙂
Совсем скоро мы представим наших спикеров, поэтому не переключайтесь 🙂
А еще, самое время зарегистрироваться на митап и забить место в своих календариках, чтобы не пропустить этот движ, ведь количество мест ограничено.
Передаем привет главному спонсору #13 митапа - Lamoda Tech 💚
Увидимся совсем скоро🤍
Это мы идем с крутыми новостями🤪
Алярм: мы открываем регистрацию на новый митап!
👉 РЕГИСТРАЦИЯ👈
В 13-ый раз команда сообщества MskVue.js соберет единомышленников в офисе Lamoda!
Вас ждут 3 доклада, розыгрыш мерча за лучший вопрос спикеру и просто тонна общения с крутыми разрабами 🙂
Совсем скоро мы представим наших спикеров, поэтому не переключайтесь 🙂
А еще, самое время зарегистрироваться на митап и забить место в своих календариках, чтобы не пропустить этот движ, ведь количество мест ограничено.
Передаем привет главному спонсору #13 митапа - Lamoda Tech 💚
Увидимся совсем скоро
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍4😢1