Привет, Шмоджи здесь. Сегодня мы будем создавать многоразовые модальные окна с помощью Vue. Если вы не знали, гифка выше — это пример модального окна. Я поискал на YouTube и понял, что все видео показывают, как создавать модальные окна, но код нельзя использовать повторно и он не очень чистый.

То, что вы создадите с помощью этого руководства, отличается, потому что вы можете без проблем интегрировать это право в большой проект. Возможно, в данный момент это не имеет смысла, так что давайте начнем, и я объясню по ходу дела.

Если вы предпочитаете видео и хотите получить более подробную информацию, то вот учебник YouTube предлагает именно это.

ПРИМЕЧАНИЕ. В этой статье я не буду подробно описывать настройку проекта. Я начинаю с базового приложения Vue, которое было только что создано с помощью vue create modals, и я использую Visual Studio Code.

Хорошо, давайте начнем.

Начальная загрузка

Как и в большинстве руководств, которые я делаю, первое, что нам нужно сделать, это загрузить и импортировать Bootstrap, чтобы мы могли получить несколько стилей. Опять же, нам не нужны эти стили, но они значительно упрощают работу, так что нам не нужно изобретать велосипед.

Загрузите его в терминал с помощью:

npm install bootstrap

Теперь откройте файл с именем main.js и вставьте его вверху:

import ‘bootstrap/dist/css/bootstrap.min.css’;

Круто, теперь у вас есть CSS-часть Bootstrap.

Модальные компоненты

Для каждого компонента я дам вам код, а затем объясню наиболее запутанные или важные части под ним. Постараюсь объяснить так, чтобы понял даже начинающий программист.

Modal.vue

Создайте структуру папок, показанную на этом рисунке, и создайте файл с именем Modal.vue внутри папки components:

Поместите этот код в Modal.vue:

<template>
  <div class="modal">
    <div class="modal-dialog">
      <div class="modal-content">
        <slot />
      </div>
    </div>
  </div>
</template>

Это все для этого файла. При этом используются стили Bootstrap под названием «modal», «modal-dialog» и «modal-content», чтобы сделать модальное выглядеть красиво без необходимости самостоятельно писать CSS. Таких стилей будет еще много, но я не буду их брать на заметку. Если у вас когда-нибудь возникнут вопросы по этому поводу, просто погуглите «Bootstrap modal».

Помимо стилей Bootstrap, ‹slot /›, пожалуй, самая запутанная часть. Всякий раз, когда вы используете этот компонент Modal.vue где-то еще, вы можете вкладывать элементы DOM внутрь него, чтобы разместить их там, где находится слот. Если это не имеет смысла, просто продолжайте, и позже, когда у нас будет рабочий пример, станет очевидно, что это значит.

Итак, следующие несколько компонентов настолько просты, что я не буду их объяснять. Кроме того, эти компоненты не являются абсолютно необходимыми, но мне нравится разбивать логику моих модальных окон таким образом, чтобы было проще создавать настраиваемые модальные окна. Обязательно поместите все это в папку components.

ModalBody.vue

<template>
  <div class="modal-body">
    <slot />
  </div>
</template>

ModalHeader.vue

<template>
  <div class="modal-header">
    <slot />
  </div>
</template>

ModalFooter.vue

<template>
  <div class="modal-footer">
    <slot />
  </div>
</template>

Итак, этот следующий компонент будет намного сложнее, поэтому обязательно прочитайте объяснения ниже, если вы запутались, и посмотрите видеоверсию, если вы все еще заблудились.

ModalRoot.vue

Этот файл является корнем, в котором ваше модальное окно будет размещено в DOM. Вы хотите, чтобы ваши модальные окна отображались на самом низком уровне, поэтому позже мы поместим это в App.vue.

Прежде всего, я объясню раздел ‹script›/script›:

import ModalService from '../services/modal.service';                       import Modal from './Modal/Modal.vue';

Это просто импорт нужных нам файлов: компонента Modal, который мы создали ранее, и файла ModalService, который мы еще не создали.

data() {
  return {
    modal: {},
  }
},

Здесь мы объявляем модальный объект, который будет содержать любое модальное окно, которое мы хотим использовать.

created() {
  ModalService.$on('open', ({ component, props, resolve, reject }) => {
    this.modal = {
      component,
      props,
      close: value => {
        this.modal = {};
        resolve(value);
      },
      dismiss: reason => {
        this.modal = {};
        reject(reason);
      },
    };
  });
}

Этот метод created() представляет собой обработчик жизненного цикла, который вызывается при первом создании компонента ModalRoot.vue. Внутри него мы настраиваем ModalService для прослушивания события под названием «open» с помощью $on(). С этим событием должны быть переданы определенные данные. Эти данные представляют собой компонент Vue, объект свойств и две функции обратного вызова, называемые resolve и reject. Эти две функции связаны с промисами Javascript… что довольно сложно и представляет собой отдельную тему.

Внутри прослушивателя событий, если слышно событие «open», то мы инициализируем наш новый модал, который покажет его на экране. Как видите, модальное окно — это просто объект, содержащий компонент, свойства и функцию закрытия и закрытия. Компонент и реквизит берутся прямо из данных, отправленных событием (мы напишем код для отправки событий позже).

close: value => {
  this.modal = {};
  resolve(value);
},
dismiss: reason => {
  this.modal = {};
  reject(reason);
},

Функция close принимает значение в качестве аргумента, а затем избавляется от текущего модального окна. После этого он разрешает промис с переданным значением. Это в основном просто означает, что после закрытия модального окна вы завершаете промис Javascript… что позволяет вам приостановить выполнение кода и запускать следующий код только после закрытия модального окна. …но мы не будем этого делать в этом уроке. То же самое и с функцией dismiss, за исключением того, что она использует reject, которая в основном делает то же самое функционально, но обычно используется для завершения промиса с ошибкой или предупреждением. Например, если кто-то ввел информацию о кредитной карте в модальном окне, а затем нажал кнопку отмены, то он должен знать, что вся введенная им информация будет потеряна, поэтому для этого было бы хорошо использовать отклонение.

Теперь поговорим о ‹шаблоне›‹/шаблоне›:

<template>
  <section :class="{ 'modal-root': modal.component }">
    <transition name="modal">
      <component
        v-if="modal"
        :is="modal.component"
        v-bind:close="modal.close"
        v-bind:dismiss="modal.dismiss"
        v-bind="modal.props"
        :class="{ 'd-block': modal.component }"
      />
    </transition>
  </section>
</template>

‹section› — это обычный HTML-элемент, я мог бы использовать ‹div›, если бы захотел. :class=”{ ‘modal-root’: modal.component }” — это условный стиль. Это говорит о том, что если modal.component не равен нулю, используйте этот стиль.

‹transition› — это компонент-оболочка, предоставляемый Vue, который позволяет вам добавлять входные/выходные переходы для любого элемента или компонента в определенных ситуациях. Если хотите, можете подробнее об этом прочитать здесь. Важно понимать, что имя, которое вы даете переходу, соответствует имени используемых вами селекторов CSS. Итак, вы видите здесь, что мы начали их имена с модального, потому что мы назвали переход, который:

.modal-enter-active,
.modal-leave-active {
  transition: all 0.25s ease-out;
}
.modal-enter,
.modal-leave-to {
  transform: translateY(25px);
  opacity: 0;
}

‹component /› используется в Vue для динамического рендеринга компонентов. Таким образом, вы можете открыть модальные окна оплаты или модальные окна предупреждений или что угодно.

v-if="modal" -› гарантирует, что компонент отображается только при наличии модального окна.
:is="modal.component" -› указывает, какой компонент отображать. Первоначально эти данные поступали из события, которое было отправлено для открытия модального окна.
v-bind:close="modal.close" -> передает функцию закрытия в качестве реквизита компоненту.
v-bind:dismiss="modal.dismiss" -> передает функцию закрытия в качестве реквизита компоненту. .
v-bind="modal.props" -› передает все реквизиты компоненту. Первоначально эти данные поступали из события, которое было отправлено для открытия модального окна.
:class="{ 'd-block': modal.component }" -› условное оформление.

CSS очень прост, поэтому не буду тратить на него место, но я объясню его подробнее в видео.

Модальный миксин

Mixins — это вещь Vue, которая позволяет вам включать определенные данные в любой файл, в который вы их импортируете.

Внутри папки modals создайте новую папку с именем mixins. Внутри этой папки создайте файл с именем ModalMixin.js и вставьте его в:

export default {
  props: {
    close: {
      type: Function,
      required: true,
    },
    dismiss: {
      type: Function,
      required: true,
    },
  },
};

Надеюсь, вы видите, что эти реквизиты предназначены для функций, которые мы определили ранее. Этот миксин делает так, что вам не нужно будет определять эти реквизиты для каждого пользовательского модального окна, которое вы создаете… вместо этого вы можете просто импортировать этот миксин. Мы сделаем это позже при создании нашего пользовательского модального окна.

Модальный сервис

Как правило, я создаю сервисы всякий раз, когда мне нужен какой-то способ абстрагирования логики, и сервис действует как интерфейс к этой логике. Компании часто делают это для сторонних библиотек. Это связано с тем, что если вы абстрагируете библиотеку и создадите свои собственные методы службы для доступа к библиотеке, если создатели этой библиотеки прекратят ее использование, вы можете просто заменить логику другой библиотекой, но созданный вами интерфейс службы останется прежним. поэтому вам не нужно перебирать все приложение, изменяя способ использования этой логики.

Итак, в этом случае Modal Service позволит нам открывать модальные окна в любом месте одним простым способом.

Внутри папки modals создайте новую папку с именем services. Внутри этой папки создайте файл с именем modal.service.js и вставьте его в:

import Vue from 'vue';
export default new Vue({
  methods: {
    open(component, props = {}) {
      return new Promise((resolve, reject) => {
        this.$emit('open', { component, props, resolve, reject });
      });
    }
  }
})

Здесь мы создаем новый экземпляр Vue с помощью одного метода с именем open. Метод open принимает компонент и свойства в качестве аргументов. Он возвращает промис, и внутри этого тела промиса генерируется событие под названием «открыть». Как видите, все данные, которые мы здесь передаем, — это именно то, что мы прослушиваем внутри ModalRoot.vue.

Теперь все, что нам нужно сделать, это создать собственное модальное окно и открыть его с помощью кнопки.

Создание пользовательского модального окна

Теперь мы можем использовать модальную реализацию, которую мы создали, для создания пользовательского модального окна! Создайте файл внутри src/components и назовите его TestModal.vue. Вставьте в него это:

Раздел ‹script› — это не что иное, как импорт вещей. Это хороший пример использования миксинов Vue.

В шаблоне вы можете увидеть, как именно используются компоненты, которые мы создали. Это довольно просто, потому что мы создали его таким образом. Если вам не нужен верхний или нижний колонтитул, не стесняйтесь их удалять.

В нижнем колонтитуле кнопки показывают, как закрыть или закрыть модальные окна. Эти две функции передаются как реквизиты в ModalRoot.vue, а наш модальный миксин указывает TestModal.vue ожидать эти реквизиты, после чего вы можете использовать методы, как видите.

App.vue — Использование нашего пользовательского модального окна

Здесь мы настроим кнопку, которая будет открывать модальное окно при нажатии. Откройте файл App.vue и вставьте его в:

Вы можете видеть, что мы импортируем ModalRoot, ModalService и TestModal. Затем есть один метод, называемый addModal(), который просто использует ModalService для открытия нашего TestModal.

В шаблоне мы размещаем <ModalRoot />, потому что именно здесь мы хотим, чтобы наш TestModal отображался. Это может немного сбивать с толку, потому что здесь мы также открываем модальное окно, но обычно в большом проекте вы будете открывать модальное окно в каком-то компоненте, вложенном во многие слои. Таким образом, наличие модального корня здесь гарантирует, что все модальные окна будут вставлены в дерево DOM на самом высоком уровне, а не случайно вложенное в несколько компонентов.

Затем у нас есть кнопка, которая открывает модальное окно по клику… вот и все!

Вы можете использовать npm run serve в терминале для запуска локального сервера и проверки браузера. Ваш пример должен выглядеть как GIF выше. Если это не так, то вам следует убедиться, что вы ничего не пропустили, или вы можете проверить видеоверсию с более подробной информацией.

Вывод

В этом руководстве вы узнали, как создать повторно используемую модальную реализацию, которую можно легко использовать в больших проектах. Он абстрагирует реализацию, так что вы можете использовать простую модальную службу для открытия модальных окон из любого места вашего проекта. Из этого руководства вы должны были узнать о нескольких концепциях программирования для начинающих и модераторов, включая обещания Javascript, примеси Vue, переходы Vue и многие другие. Я надеюсь, что я смог помочь вам сегодня. Если это так, не стесняйтесь проверить мой канал YouTube. Если у вас есть какие-либо вопросы, пожалуйста, прокомментируйте ниже или на видео, и я посмотрю, что я могу сделать.

Шмоджи вон!

🐱‍👤 Подписывайтесь на мои социальные сети, чтобы быть в курсе:

Ютуб, Твич