Vue二次封装element弹窗

预览

Snipaste_2025-06-11_14-16-32.png

代码

<template>
  <el-dialog
      v-model="visible"
      :title="title"
      :width="width"
      :fullscreen="fullscreen"
      :top="top"
      :modal="modal"
      :append-to-body="appendToBody"
      :lock-scroll="lockScroll"
      :custom-class="customClass"
      :open-delay="openDelay"
      :close-delay="closeDelay"
      :close-on-click-modal="closeOnClickModal"
      :close-on-press-escape="closeOnPressEscape"
      :show-close="showClose"
      :before-close="beforeClose"
      :draggable="draggable"
      :center="center"
      :destroy-on-close="destroyOnClose"
      @open="handleOpen"
      @opened="handleOpened"
      @close="handleClose"
      @closed="handleClosed"
  >
    <!-- 内容插槽 -->
    <slot></slot>

    <!-- 底部按钮插槽 -->
    <template #footer v-if="showFooter">
      <slot name="footer">
        <span class="dialog-footer">
          <el-button @click="handleCancel">
            {{ $t(`base.cancel`) }}
          </el-button>
          <el-button type="primary" @click="handleConfirm">
            {{ $t(`base.confirm`) }}
          </el-button>
        </span>
      </slot>
    </template>
  </el-dialog>
</template>

<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()

const props = defineProps({
  // 控制显示隐藏
  modelValue: {
    type: Boolean,
    default: false
  },
  // 标题
  title: {
    type: String,
    default: '提示'
  },
  // 宽度
  width: {
    type: String,
    default: '50%'
  },
  // 是否全屏
  fullscreen: {
    type: Boolean,
    default: false
  },
  // 距离顶部距离
  top: {
    type: String,
    default: '15vh'
  },
  // 是否显示遮罩层
  modal: {
    type: Boolean,
    default: true
  },
  // 是否插入到body元素上
  appendToBody: {
    type: Boolean,
    default: false
  },
  // 是否锁定滚动
  lockScroll: {
    type: Boolean,
    default: true
  },
  // 自定义类名
  customClass: {
    type: String,
    default: ''
  },
  // 打开延迟
  openDelay: {
    type: Number,
    default: 0
  },
  // 关闭延迟
  closeDelay: {
    type: Number,
    default: 0
  },
  // 点击遮罩层是否关闭
  closeOnClickModal: {
    type: Boolean,
    default: false
  },
  // 按ESC键是否关闭
  closeOnPressEscape: {
    type: Boolean,
    default: true
  },
  // 是否显示关闭按钮
  showClose: {
    type: Boolean,
    default: true
  },
  // 关闭前的回调
  beforeClose: {
    type: Function,
    default: null
  },
  // 是否可拖拽
  draggable: {
    type: Boolean,
    default: false
  },
  // 是否居中显示
  center: {
    type: Boolean,
    default: false
  },
  // 关闭时销毁元素
  destroyOnClose: {
    type: Boolean,
    default: false
  },
  // 是否显示底部
  showFooter: {
    type: Boolean,
    default: true
  },
  // 取消按钮文字
  cancel: {
    type: String,
    default: '取消'
  },
  // 确认按钮文字
  confirm: {
    type: String,
    default: '确定'
  }
})

const emit = defineEmits([
  'update:modelValue',
  'open',
  'opened',
  'close',
  'closed',
  'cancel',
  'confirm'
])

const visible = ref(false)

// 监听modelValue变化
watch(() => props.modelValue, (val) => {
  visible.value = val
})

// 监听visible变化
watch(visible, (val) => {
  emit('update:modelValue', val)
})

// 打开事件
const handleOpen = () => {
  emit('open')
}

// 打开动画结束
const handleOpened = () => {
  emit('opened')
}

// 关闭事件
const handleClose = () => {
  emit('close')
}

// 关闭动画结束
const handleClosed = () => {
  emit('closed')
}

// 取消按钮
const handleCancel = () => {
  visible.value = false
  emit('cancel')
}

// 确认按钮
const handleConfirm = () => {
  emit('confirm')
}
</script>

<style scoped>
.dialog-footer {
  display: flex;
  justify-content: flex-end;
}
</style>

使用

<BaseDialog
      width="550px"
      v-model="showDialog"
      :title="dialogTitle"
      @confirm="confirmChange"
      @cancel="resetForm"
  >
  </BaseDialog>
评论区
头像
文章目录