Как в Nuxt 3 можно реализовать функционал подтверждения действий пользователя?

Как можно передать компоненту формы информацию о типе действия, которое нужно выполнить при нажатии на кнопку "Да" в общем режиме редактирования для администраторов? Я хотел бы избежать создания отдельной формы для каждой сущности (статья, комментарий и другие).
  • 21 ноября 2024 г. 16:23
Ответы на вопрос 2
В Nuxt 3 есть несколько способов реализации функционала подтверждения действий пользователя, не создавая отдельные формы для каждой сущности. Вы можете использовать компоненты и динамические свойства для передачи информации о типе действия. Вот пример подхода:

1. **Создайте компонент подтверждения**:
   Вы можете создать общий компонент для подтверждения действий. Например, назовем его `ConfirmationModal.vue`.

```vue
<template>
  <div v-if="isVisible" class="modal">
    <div class="modal-content">
      <p>{{ message }}</p>
      <button @click="confirm">Да</button>
      <button @click="cancel">Нет</button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const props = defineProps(['message', 'isVisible'])
const emit = defineEmits(['onConfirm', 'onCancel'])

const confirm = () => {
  emit('onConfirm')
}

const cancel = () => {
  emit('onCancel')
}
</script>

<style>
.modal {
  /* Стили для модального окна */
}
</style>
```

2. **Используйте этот компонент в вашей форме**:
   В вашем основном компоненте, где располагается форма, можно использовать `ConfirmationModal`. Предположим, у вас есть форма для редактирования сущностей:

```vue
<template>
  <div>
    <form @submit.prevent="handleSubmit">
      <!-- Поля формы здесь -->
      <button @click="openConfirmation">Удалить</button>
    </form>

    <ConfirmationModal
      v-if="isModalVisible"
      :message="confirmationMessage"
      :isVisible="isModalVisible"
      @onConfirm="executeAction"
      @onCancel="closeConfirmation"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import ConfirmationModal from './ConfirmationModal.vue'

const isModalVisible = ref(false)
const confirmationMessage = ref('Вы уверены, что хотите выполнить это действие?')

const openConfirmation = () => {
  isModalVisible.value = true
}

const closeConfirmation = () => {
  isModalVisible.value = false
}

const executeAction = () => {
  // Логика выполнения действия
  console.log('Действие выполнено')
  
  // Закрываем модал
  closeConfirmation()
}

const handleSubmit = () => {
  // Логика обработки данных формы
  console.log('Данные формы отправлены')
}
</script>
```

3. **Передача информации о действии**:
   В `handleSubmit` или в обработчике, который привязан к кнопке, вы можете задавать переменные, чтобы передать в `ConfirmationModal` нужное сообщение или тип действия. Например, можно передавать такие параметры, как тип сущности и само действие.

Таким образом, вы реализуете общий компонент, который можно будет переиспользовать для различных дублей и типов действий. Это позволяет избегать дублирования кода, а также упрощает поддержку и расширение функционала приложения.
Я к примеру сделал так 

<UiConfirmButton
  color="success"
  :loading="loading"
  block
  message="После публикации билеты станут доступны для продажи и изменить шаблон будет нельзя."
  label="Опубликовать"
  @confirm="fetch"
/>


<script setup lang="ts">
import type { ButtonProps } from '@nuxt/ui';

const emit = defineEmits<{
  (e: 'confirm'): void
}>();

defineOptions({
  inheritAttrs: false,
});

interface Props extends ButtonProps {
  message?: string
  confirmLabel?: string
  confirmColor?: ButtonProps['color']
}

const props = defineProps<Props>();

const { message, confirmLabel, confirmColor, ...buttonProps } = props;

const open = ref(false);

const confirm = () => {
  emit('confirm');
  open.value = false;
};
</script>

<template>
  <UModal
    v-model:open="open"
    :title="$t('confirm.label')"
  >
    <UButton v-bind="buttonProps">
      <template v-if="$slots">
        <slot />
      </template>
    </UButton>
    <template #body>
      <UAlert
        variant="soft"
        icon="i-tabler-alert-triangle"
        :title="message || $t('confirm.message')"
        color="error"
      />
    </template>
    <template #footer>
      <div class="flex gap-x-2 w-full justify-end pb-safe">
        <UButton
          :label="$t('button.cancel')"
          color="neutral"
          variant="outline"
          @click="open = false"
        />
        <UButton
          :label="confirmLabel || $t('button.confirm')"
          :color="confirmColor || 'success'"
          @click="confirm"
        />
      </div>
    </template>
  </UModal>
</template>

<style scoped lang="scss">

</style>
Похожие вопросы