@alexsmirnovdotcom

Vue 3. Как лучше встроить модальное окно для каждого элемента из списка?

Допустим имеется таблица с большим количеством элементов, кликнув на любой из них открывается модальное окно с деталями этого элемента (допустим список счетов и по клику на каждый открывается форма редактирования счета).

Компонент с формой редактирования: модальное окно, и сама форма, в пропсы которой передается ID документа и уже сама форма подгружает нужные данные.

Как лучше реализовать такой механизм?
1) В каждой строке использовать компонент (например ссылка или кнопка), в котором будет вставлен компонент модального окна с формой и которое будет открываться при клике на компонент.
Плюсы: Возможность вызывать неограниченное количество разных модалок, они будут просто накладываться поверх друг друга.
Минусы: В каждой строке таблицы будет куча вложенных компонентов, которые грузят память и процессор и которые вообще никак не используюсят пока пользователь не кликнет на кнопку / ссылку на конкрентной строке.

2) Вставить компонент модального окна с формой допустим в layout файл который используется на всех страницах, и работать с ним через store (Pinia или Vuex, не важно). В таблице при клике на (кнопку / ссылку) элемента, будут просто меняться данные в сторе, а в модальном окне эти изменения соответственно будут отслеживаться.
Плюсы: Один единственный компонент, который просто меняет свое состояние в зависимости от значений в глобальном хранилище.
Минусы: Сложно реализовать множественное переиспользование этого компонента.

Какой вариант по вашему лучше и почему?
Как можно реализовать множественное использование одного компонента, если его состояние зависит от глобального хранилища? (Например в форме редактирования счета, есть список связанных счетов. Как открыть их, не закрывая текущее модальное окно и не меняя его содержимое? Тоесть как открыть еще одно такое модальное окно с формой другого документа?)

Возможно есть еще какие либо варианты? Буду рад если поделитесь тем, как вы это реализуете или ссылками на материалы по теме.
Вопрос не про конкретную реализацию, а про то как правильно огранизовывать такие моменты, что бы можно было переиспользовать тяжелые компоненты и при этом не тратить большое количество ресурсов на бесконечную вложенность.
  • Вопрос задан
  • 1268 просмотров
Решения вопроса 1
@misterobot404
Если в каждом элементе списка используется компонент модалки, как правило, он никогда не дублируется, а инициализируется каждый раз новым стейтом при нажатии на элемент списка. Но у вас редкий случай, нужно одновременно открывать несколько таких модалок, решение: используйте массив динамических компонентов.

При нажатии на элемент в списке, в массив компонентов заносится элемент с нужным названием и стейтом для инициализации, при закрытии модалки можете перехватывать событие и удалить компонент из этого массива.

<component
      v-for="modal in array_of_modal"
      :is="modal.component_name"
      v-bind="modal.props">
  </component>

 array_of_modal: [
        {
          component_name: "component_name_1",
          props: {}
        },
        {
          component_name: "component_name_2",
          props: {}
        }
      ]
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
delphinpro
@delphinpro
frontend developer
Вы сами определили плюсы и минусы обоих подходов.

Множественное переиспользование общего компонента решается массивом данных в сторе.
Грубо так:

store = {
  modals: [
    // {}  - объект с данными для модалки
  ];
}


<template v-for="modal in store.modals">
  <my-modal-component v-bind="modal"/>
</template>
Ответ написан
Комментировать
Adamos
@Adamos
Модальное окно, по определению - перехватывает фокус и блокирует обращение к другим элементам, пока не будет закрыто. У вас явно что-то другое... и вместо вызова кучи перекрывающих друг друга модалок имеет смысл подумать над элементом интерфейса, в котором будет список вызванных форм, например, с возможностью закрыть каждую. Без всей лишней и ненужной в этом случае атрибутики модального окна.

Вот, например, в виндах последних версий вместо кучи всплывающих оповещений есть виджет, в котором они все отображаются, когда у вас дойдут до него руки. Что-то подобное, но, конечно, открывающееся автоматически, когда вы вызвали очередную форму.
Ответ написан
@sourlyparadise
как вариант..можно разместить компонент с модальным окном под таблицей, расшарить метод открытия через defineExpose и через него же передавать данные в окно, соответственно компонент получится всего один с динамическими данными.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы