createSharedComposableЕсли бы меня спросили лучшие паттерны для освоения во Vue, я бы точно назвал одним из них s
hared composable. Почему и что это за фрукт такой?
ПроисхождениеПервое упоминание о shared composable было в
RFC Vue посвященному Effect Scope. И там говорится о примере композабла useMouse который слушает перемещения мышки и возвращает это в виде реактивных переменных координат. И вроде логично, что это не самое легковесное действие. А если это нужно множеству компонентов? Да каждый компонент использующий useMouse подписывается на него и это становится уже ощутимо. Тогда почему бы просто не вынести в глобальный STM как Pinia? Отличный вариант, но он будет работать даже когда нет никого кому нужны эти данные. И вот тут на помощь приходит
shared composable он умеет как STM шарить данные на множество инстансов, но при этом если никто его не использует, то "стор" уничтожается! При этом сам паттерн универсальный и все что вам нужно это обернуть обычный композабл в createSharedComposable. И да, как только все компоненты использующие useMouse будут размонтированы s
hared 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, однозначно рекомендую к изучению