Vue3 + TS + Element-Plus 封装的 Dialog 弹窗组件

弹窗组件中自定义了表头增加了全屏,svg-icon 没有的话可能会报错,换成自己的图标就可以

javascript 复制代码
<template>
  <el-dialog
    :dialogHeight="dialogHeight"
    :title="dialogTitle"
    class="dialog min-w-70"
    v-model="dialogVisible"
    append-to-body
    :modal="dialogModal"
    :fullscreen="fullscreen"
    :close-on-click-modal="dialogClickModalClose"
    :draggable="dialogDraggable"
    :show-close="false"
    :width="dialogWidth"
    :align-center="dialogAlignCenter"
    :center="dialogContentCenter"
    @open="open"
    @close="close"
  >
    <template #header>
      <div class="flex justify-between items-content">
        <div class="titleClass">{{ dialogTitle }}</div>
        <div class="icon-content">
          <!-- <el-icon class="single-uploader__icon text-[12px]">
              <i-ep-minus v-if="fullscreen" />
              <i-ep-plus v-else />
            </el-icon>-->
          <div :title="!fullscreen ? '全屏' : '还原'">
            <svg-icon
              class="icon-item-content"
              v-if="showExpand"
              @click="zoom"
              :icon-class="fullscreen ? 'fullscreen-exit' : 'fullscreen'"
            />
          </div>
          <div title="关闭">
            <el-icon
              v-if="showClose"
              @click="close"
              title="关闭"
              class="single-uploader__icon icon-item-content"
            >
              <i-ep-close />
            </el-icon>
          </div>
        </div>
      </div>
    </template>
    <div :style="{ height: dialogBodyHeight }" class="overflow-a0uto">
      <slot></slot>
    </div>
    <template #footer v-if="dialogFooterBtn">
      <el-button type="primary" @click="SaveSubmit">确 定</el-button>
      <el-button @click="CloseSubmit">取 消</el-button>
    </template>
  </el-dialog>
</template>
javascript 复制代码
<script setup lang="ts">
// 【接口】接受传参字段
interface IProps {
  // 是否显示 Dialog
  visible: boolean;
  // 对话框的标题
  dialogTitle?: string;
  // 内容区域高度
  dialogHeight?: string;
  // 对话框的宽度
  dialogWidth?: string;
  // 是否需要遮罩层
  dialogModal?: boolean;
  // 是否水平垂直对齐对话框
  dialogAlignCenter?: boolean;
  // 是否让 Dialog 的 header 和 footer 部分居中排列
  dialogContentCenter?: boolean;
  // 是否可以通过点击 modal 关闭 Dialog
  dialogClickModalClose?: boolean;
  // 为 Dialog 启用可拖拽功能
  dialogDraggable?: boolean;
  // 是否显示底部按钮
  dialogFooterBtn?: boolean;
  // 是否显示全屏按钮
  showExpand?: boolean;
  // 是否显示关闭按钮
  showClose?: boolean;
}

// 初始化默认参数
const props = withDefaults(defineProps<IProps>(), {
  dialogTitle: "默认标题",
  dialogWidth: "40%",
  dialogHeight: "auto",
  dialogModal: true,
  dialogAlignCenter: false,
  dialogContentCenter: false,
  dialogClickModalClose: false,
  dialogDraggable: false,
  dialogFooterBtn: true,
  showExpand: false,
  showClose: true,
});

const emit = defineEmits([
  "save",
  "cancellation",
  "open",
  "close",
  "zoom",
  "update:visible",
]);

const dialogVisible = useVModel(props, "visible", emit);
let fullscreen = ref(false);
const dialogBodyHeight = ref<string | number>(); // 初始值为字符串类型

// watch监听
watch(
  [() => props.visible, () => props.dialogHeight, () => props.dialogFooterBtn],
  () => {
    nextTick(() => {
      menuDialogZoom();
    });
  },
  { deep: true, immediate: true }
);

// 保存提交回调函数
const SaveSubmit = () => {
  emit("save"); //emit方法供父级组件调用
};

// 取消保存回调函数
const CloseSubmit = () => {
  emit("cancellation"); //emit方法供父级组件调用
};

// 打开事件回调函数
const open = () => {
  emit("open"); //emit方法供父级组件调用
};

// 关闭事件回调函数(当显示头部关闭按钮时需调用该回调函数方法 -> dialogShowClose = true 反之)
const close = () => {
  emit("close"); //emit方法供父级组件调用
};

// 缩放弹窗
const zoom = () => {
  fullscreen.value = !fullscreen.value;
  menuDialogZoom();
  console.log(fullscreen.value);
  emit("zoom", fullscreen.value); //emit方法供父级组件调用
};

/* 分配权限缩放弹窗 */
const menuDialogZoom = () => {
  if (props.visible && fullscreen.value && props.dialogFooterBtn) {
    dialogBodyHeight.value = "calc(100vh - 120px)";
  } else if (props.visible && fullscreen.value && !props.dialogFooterBtn) {
    dialogBodyHeight.value = "calc(100vh - 80px)";
  } else {
    dialogBodyHeight.value = props.dialogHeight;
  }
};
</script>
javascript 复制代码
<style scoped>
.titleClass {
  font-weight: bold;
}

.icon-content {
  display: flex;
  align-items: center;
}

.icon-item-content {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #909399;
}

.icon-item-content:nth-child(1) {
  margin-right: 10px;
}

.icon-item-content:hover {
  color: #1f6feb;
  cursor: pointer;
}

.single-uploader__icon {
  font-size: 18px;
}
</style>

使用案例

javascript 复制代码
    <Dialog
      dialogHeight="350px"
      v-model:visible="menuDialogVisible"
      :dialogTitle="'【' + checkedRole.name + '】权限分配'"
      :dialogDraggable="true"
      dialogWidth="30%"
      @close="menuDialogVisible = false"
      @save="handleRoleMenuSubmit"
      @cancellation="menuDialogVisible = false"
    >
      内容区域
    </Dialog>

弹窗相关数据

javascript 复制代码
let menuDialogVisible = ref(false);
相关推荐
王小王和他的小伙伴6 分钟前
解决 vue3 中 echarts图表在el-dialog中显示问题
javascript·vue.js·echarts
FeboReigns9 分钟前
C++简明教程(10)(初识类)
c语言·开发语言·c++
学前端的小朱10 分钟前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具
好名字08211 小时前
前端取Content-Disposition中的filename字段与解码(vue)
前端·javascript·vue.js·前端框架
摇光931 小时前
js高阶-async与事件循环
开发语言·javascript·事件循环·宏任务·微任务
沐泽Mu1 小时前
嵌入式学习-QT-Day09
开发语言·qt·学习
隐形喷火龙1 小时前
element ui--下拉根据拼音首字母过滤
前端·vue.js·ui
小猿_001 小时前
C语言实现顺序表详解
c语言·开发语言
余~~185381628001 小时前
NFC 碰一碰发视频源码搭建技术详解,支持OEM
开发语言·人工智能·python·音视频
GOATLong2 小时前
c++智能指针
开发语言·c++