Comments 17
Если честно, немного не понятно, зачем плодить модульные broadcast и сами $module, когда можно общаться через единую шину (в примере $rootBroadcast) с помощью сообщений, одним из обязательных параметров которого будет имя модуля. причем, если нет желание писать имя модуля в событии явно, его также можно задекларировать в прототипе вуя как $moduleName. Наличие класса типа ModuleEvent даст возможность понимать где какие события отсылаются/обрабатываются. Это может быть полезным при погружении и фикса багов.
А можно все это организовать через нативный window.postMessage, который не зависит от фреймворков и здорово спасает, если у вас их, вдруг, несколько на проект.
Поздравляю вас, вы в одном решении использовали кажется все антипаттерны вью.
Расширение прототипа — во вью3 оставят только как штуку для обратной совместимости легаси плагинов. Больше не рекомендуется к использованию.
Во вью3 с новым композишн апи нельзя использовать миксины.
Во вью3 удалят $on, $off, $once.
Во вью3 удалят как минимум из доки упоминания $root, $parent
Пожалуйста, не делайте так в ваших приложениях. Для реализации Pub\Sub есть множество готовых решений и они не требуют какой-то специальной интеграции для Vue.
Здесь действительно целый огород из плохих практик:
- Шина на Vue (готовится стать deprecated во Vue 3), считается плохой практикой и разработчики Vue это признали сами.
- Обращение к $parent — повышает связанность компонентов и работает неявно. Такой код будет очень сложно поддерживать потому что непонятно кто что вызывает.
- Миксины. Особенно глобальные миксины. О минусах миксинов писали много раз, но я повторю: конфликты имён, непонятно что добавляет миксин без чтения кода самого миксина, сложно определить кто пропатчил контекст компонента когда миксинов несколько.
Для хранения глобального состояния и глобальной обработки событий используйте Vuex или Provide\Inject. Если вам нужна связь только по событиям используйте Pub\Sub (но я не смог придумать такой кейс если честно).
0. Задача с Pub/Sub действительно довольно тривиальная и реализаций есть множество — тот же Rx например. Дело в том что конкретно это решение призвано решить очень утилитарную проблему максимально просто и быстро и быть максимально прозрачным в использовании — поэтому хотелось бы решить все без дополнительных зависимостей и желательно без доп документации
1. На момент написания этого плагина шина на Vue не являлась плохой практикой. Да и в принципе шина событий это паттерн проектирования — ее плохое использование может быть плохой практикой, а сама по себе она просто инструмент. Как вы сами отметили существует много альтернативных решений — мы использовали конкретно Vue только из соображений зависимостей
2. В целом это совершенно верно в случаях обычного кода и мы не допускаем такого в компонентах. Но в данном случае мы имеем дело с генеричным кодом. Обращение к $parent здесь служит для оценки контекста и по факту именно резолвит связанность в ее прикладном понимании (грубо говоря тот оверхед, который необходим чтобы решение заработало в новом контексте). Опять же результат отработки кода консистентен не зависимо от результатов анализа $parent — событие все равно будет запущено или проксированно. Поэтому лично я не вижу в этом проблемы
3. Совершенно согласен с вашим утверждением насчет миксинов. Не скажу что совсем нет случаев оправданных для их использования, но они единичны и использовать их надо аккуратно. В данном случае, отмечу снова, мы говорим не про код компонентов, а про генеричное расширение общее для всего приложения, поэтому нет необходимости держать в голове что-то специфичное конкретному контексту — только приложению целиком.
Про provide/inject я написал выше. В целом мне кажется что каждый выбирает инструменты исходя из конкретной задачи. Я не говорю, что этот вариант решения единственный, или лучший, или универсальный, либо что с его помощью нельзя выстрелить в ногу. Это просто конкретное решение конкретной задачи, который можно использовать (или не использовать) по своему усмотрению
Здесь вопрос организации процесса разработки конечно, поэтому за всех не могу говорить, могу только за свою команду)
У нас с этим не возникло проблем по двум причинам:
1. При внедрении плагина мы сразу озвучили какие случаи мы решаем с помощью шины, а какие нет. На практике каждое ее использование обсуждается и согласовывается, потому что случаев ее использования очень не много — примерно 5%. Дело просто в том, что эти 5% при других способах порождают неоправданно большой оверхэд если делать их через Vuex или однонаправленный поток. Если буквально — результат асинхронного действия как-то отражается на модели данных и это можно наблюдать через watch? Используй Vuex. Если нет — используй шину.
2. Контроль на код-ревью)
10 строк кода, которые уменьшат боль от вашего проекта на Vue