Vue state management: Pania stores или composables с глобальные рефами?
На Reddit прошла интересная дискуссия с 25К+ просмотрами по вопросу предпочтений разработчиков при необходимости управлять глобальным состоянием во Vue 3. Ниже её итоги.
Reddit подводит итоги года по частоте посещения /r/vuejs из разных стран мира
Вопрос автором был поставлен так: Зачем использовать Pinia вместо глобальных ref’s?
В своих проектах я использую composable функции с глобальным состоянием, как описано в документации Vue.
Каждая функция представляет собой объект бизнес-логики — например, useShoppingCart
, useAppConfig
и т. д. — и инкапсулирует реактивное состояние и бизнес-логику.
Этот подход часто критикуют и рекомендуют использовать Pinia.
Я знаю о поддержке SSR и возможностях Devtools в Pinia, но это не мой случай — они мне не нужны.
Так почему же, за исключением нужды в SSR и Devtools, я должен использовать Pinia?
Плюсы composable сторов на глобальных рефах очевидны:
Простота
Нативность по отношению к фреймворку
Отсутствие зависимостей означает отсутствие будущей ситуации «RIP Vuex» с переписыванием 50% кодовой базы проекта
API Composition выглядит очень зрелым и стабильным и вряд ли сильно изменится в ближайшем будущем (по сравнению с переходом Vue 2 → Vue 3).
Позволяет использовать всю мощь Reactivity API вместо жесткой Reactive обертки для переменных у Pinia. Разница в производительности может быть огромной.
Минусы?
Было получено на данный момент 36 комментариев, которые можно скомпилировать в следующие выводы:
Большинство согласилось, что если не нужна поддержка SSR и интеграция с Devtools, то работа с Reactivity API напрямую и инкапсуляция реактивного состояния и бизнес логики в composable функции вполне возможна. Для многих это лучше использования Pinia.
Работа с Reactivity API позволяет делать многое, что не позволяет Pinia — например, делать сторы на TypeScript классах.
Был предложен лайфхак — во время разработки импортировать реактивные данные из composable сторов в Pinia, и тогда возможно использование Devtools. При билде для продакшна Pinia уже нет.
Из-за того, что Pinia оборачивает всё в Reactive (даже в режиме
setup stores
) происходит сильная потеря производительности при работе с Ref или ShallowRef, которые не используют Proxy. Evan You говорил об этом, но плюсы от использования Proxy по сравнению с самописной реализацией реактивности во Vue 2, перекрывают минусы по его словам.Единственный аргумент в пользу Pinia — унификация работы со стором в команде.
Очень интересный пример использования TypeScript классов в качестве стора через composable был предложен пользователем ferferga. Он дает возможность использовать приватные поля, сеттеры и геттеры (без .value), first class type support, что было бы невозможно в случае с Pinia. Данный пример не в качестве рекомендации, но как демонстрация того, что возможно с Composition API