Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Недавно столкнулся с интересной задачей: нужно создать модальные окна, которые бы рендерились с помощью вызовов функций. После ресерча различных библиотек и статей собрал все ведомые мне способы в одной статье. Под катом подробнее.
Мы специально не будем рассматривать стандартное размещение попапов с помощью teleport
и v-show
с реактивным состоянием внутри родительского компонента. Данная статья рассматривает случаи, когда попапы не должны засорять другие компоненты данными для своих пропсов. Также мы не будем рассматривать паттерн UIState
, где для каждого попапа в сторе (Vuex/Pinia) прописывается состояние открыт ли попап.
Эмиттинг ивентов
Данный способ основывается на паттерне pub/sub. К слову это самый примитивный способ и некрасивый способ, что можно придумать.
Мы можем реализовать паттерн pub/sub сами, это сделать не так уж и сложно, внизу предоставлена примитивная реализация pub/sub, которая будет только вызывать ивенты и подписываться на них.
// Список заранее прописанных ивентов
export enum EmitterEvents {
SHOW_POPUP
}
// Интерфейс для эмиттера (объекта, который будет содержать все функции
// которые нужно вызвать при тригере)
type Emitter = Record<EmitterEvents, Array<() => void>>;
const emitter: Emitter = {
[EmitterEvents.SHOW_POPUP]: []
};
// Используем composable для того чтобы вернуть нужные нам функции
export const useEmitter = () => {
const trigger = (event: EmitterEvents) => emitter[event].forEach(cb => cb());
const bind = (event: EmitterEvents, callback: () => void) => {
if (emitter[event].includes(callback)) {
console.warn('This callback is already in emitter!