feat: 函数式弹框组件添加全屏、退出全屏操作按钮 (#546)

feat: 函数式弹框组件添加全屏、退出全屏操作按钮
This commit is contained in:
许诺 2023-05-14 00:13:10 +08:00 committed by GitHub
parent 5f3210f69e
commit 0b8412c109
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 88 additions and 16 deletions

View File

@ -1,13 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from "vue";
import { isFunction } from "@pureadmin/utils";
import { import {
type DialogOptions, closeDialog,
type ButtonProps,
type EventType,
dialogStore, dialogStore,
closeDialog type EventType,
type ButtonProps,
type DialogOptions
} from "./index"; } from "./index";
import { ref, computed } from "vue";
import { isFunction } from "@pureadmin/utils";
import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
const fullscreen = ref(false);
const footerButtons = computed(() => { const footerButtons = computed(() => {
return (options: DialogOptions) => { return (options: DialogOptions) => {
@ -47,11 +51,22 @@ const footerButtons = computed(() => {
}; };
}); });
const fullscreenClass = computed(() => {
return [
"el-icon",
"el-dialog__close",
"-translate-x-2",
"cursor-pointer",
"hover:!text-[red]"
];
});
function eventsCallBack( function eventsCallBack(
event: EventType, event: EventType,
options: DialogOptions, options: DialogOptions,
index: number index: number
) { ) {
fullscreen.value = options?.fullscreen ?? false;
if (options?.[event] && isFunction(options?.[event])) { if (options?.[event] && isFunction(options?.[event])) {
return options?.[event]({ options, index }); return options?.[event]({ options, index });
} }
@ -69,25 +84,49 @@ function handleClose(
<template> <template>
<el-dialog <el-dialog
class="pure-dialog"
v-for="(options, index) in dialogStore" v-for="(options, index) in dialogStore"
:key="index" :key="index"
v-bind="options" v-bind="options"
v-model="options.visible" v-model="options.visible"
@opened="eventsCallBack('open', options, index)" :fullscreen="fullscreen ? true : options?.fullscreen ? true : false"
@close="handleClose(options, index)" @close="handleClose(options, index)"
@opened="eventsCallBack('open', options, index)"
@openAutoFocus="eventsCallBack('openAutoFocus', options, index)" @openAutoFocus="eventsCallBack('openAutoFocus', options, index)"
@closeAutoFocus="eventsCallBack('closeAutoFocus', options, index)" @closeAutoFocus="eventsCallBack('closeAutoFocus', options, index)"
> >
<!-- header --> <!-- header -->
<template <template
v-if="options?.headerRenderer" v-if="options?.fullscreenIcon || options?.headerRenderer"
#header="{ close, titleId, titleClass }" #header="{ close, titleId, titleClass }"
> >
<div
v-if="options?.fullscreenIcon"
class="flex items-center justify-between"
>
<span :id="titleId" :class="titleClass">{{ options?.title }}</span>
<i
v-if="!options?.fullscreen"
:class="fullscreenClass"
@click="fullscreen = !fullscreen"
>
<IconifyIconOffline
class="pure-dialog-svg"
:icon="
options?.fullscreen
? ExitFullscreen
: fullscreen
? ExitFullscreen
: Fullscreen
"
/>
</i>
</div>
<component <component
v-else
:is="options?.headerRenderer({ close, titleId, titleClass })" :is="options?.headerRenderer({ close, titleId, titleClass })"
/> />
</template> </template>
<!-- default -->
<component <component
v-bind="options?.props" v-bind="options?.props"
:is="options.contentRenderer({ options, index })" :is="options.contentRenderer({ options, index })"

View File

@ -15,8 +15,10 @@ type DialogProps = {
title?: string; title?: string;
/** `Dialog` 的宽度,默认 `50%` */ /** `Dialog` 的宽度,默认 `50%` */
width?: string | number; width?: string | number;
/** 是否为全屏 `Dialog`,默认 `false` */ /** 是否为全屏 `Dialog`(会一直处于全屏状态,除非弹框关闭),默认 `false``fullscreen` 和 `fullscreenIcon` 都传时只有 `fullscreen` 会生效 */
fullscreen?: boolean; fullscreen?: boolean;
/** 是否显示全屏操作图标,默认 `false``fullscreen` 和 `fullscreenIcon` 都传时只有 `fullscreen` 会生效 */
fullscreenIcon?: boolean;
/** `Dialog CSS` 中的 `margin-top` 值,默认 `15vh` */ /** `Dialog CSS` 中的 `margin-top` 值,默认 `15vh` */
top?: string; top?: string;
/** 是否需要遮罩层,默认 `true` */ /** 是否需要遮罩层,默认 `true` */

View File

@ -110,6 +110,10 @@ html.dark {
&:hover { &:hover {
color: rgb(255 255 255 / 85%) !important; color: rgb(255 255 255 / 85%) !important;
background-color: rgb(255 255 255 / 12%); background-color: rgb(255 255 255 / 12%);
.pure-dialog-svg {
color: rgb(255 255 255 / 85%) !important;
}
} }
} }
} }

View File

@ -69,6 +69,19 @@
} }
} }
.pure-dialog {
.pure-dialog-svg {
color: var(--el-color-info);
}
.el-dialog__headerbtn {
top: 20px;
right: 14px;
width: 24px;
height: 24px;
}
}
/* 全局覆盖element-plus的el-dialog、el-drawer、el-message-box、el-notification组件右上角关闭图标的样式表现更鲜明 */ /* 全局覆盖element-plus的el-dialog、el-drawer、el-message-box、el-notification组件右上角关闭图标的样式表现更鲜明 */
.el-dialog__headerbtn, .el-dialog__headerbtn,
.el-message-box__headerbtn { .el-message-box__headerbtn {
@ -94,6 +107,10 @@
color: rgb(0 0 0 / 88%) !important; color: rgb(0 0 0 / 88%) !important;
text-decoration: none; text-decoration: none;
background-color: rgb(0 0 0 / 6%); background-color: rgb(0 0 0 / 6%);
.pure-dialog-svg {
color: rgb(0 0 0 / 88%) !important;
}
} }
} }
} }

View File

@ -70,7 +70,7 @@ const activities = [
placement="bottom" placement="bottom"
> >
<div class="message"> <div class="message">
vue-pure-admin是基于Vue3.0+TypeScript+Vite2.0+Element-Plus编写的一套后台管理系统 vue-pure-admin是基于Vue3.0+TypeScript+Vite+Element-Plus编写的一套后台管理系统
</div> </div>
</el-timeline-item> </el-timeline-item>
</el-timeline> </el-timeline>

View File

@ -28,19 +28,19 @@ Object.keys(devDependencies).forEach(key => {
<template> <template>
<div> <div>
<el-card class="box-card mb-4" shadow="never"> <el-card class="mb-4 box-card" shadow="never">
<template #header> <template #header>
<div class="card-header"> <div class="card-header">
<span class="font-medium">关于</span> <span class="font-medium">关于</span>
</div> </div>
</template> </template>
<span style="font-size: 15px"> <span style="font-size: 15px">
Pure-Admin 是一个基于Vue3Vite2TypeScriptElement-Plus Pure-Admin 是一个基于Vue3ViteTypeScriptElement-Plus
的中后台解决方案它可以帮助您快速搭建企业级中后台提供现成的开箱解决方案及丰富的示例原则上不收取任何费用及版权可以放心使用不过如需二次开源比如用此平台二次开发并开源请联系作者获取许可 的中后台解决方案它可以帮助您快速搭建企业级中后台提供现成的开箱解决方案及丰富的示例原则上不收取任何费用及版权可以放心使用不过如需二次开源比如用此平台二次开发并开源请联系作者获取许可
</span> </span>
</el-card> </el-card>
<el-card class="box-card m-4" shadow="never"> <el-card class="m-4 box-card" shadow="never">
<template #header> <template #header>
<div class="card-header"> <div class="card-header">
<span class="font-medium">项目信息</span> <span class="font-medium">项目信息</span>
@ -49,7 +49,7 @@ Object.keys(devDependencies).forEach(key => {
<PureDescriptions :columns="columns" border :column="3" align="left" /> <PureDescriptions :columns="columns" border :column="3" align="left" />
</el-card> </el-card>
<el-card class="box-card m-4" shadow="never"> <el-card class="m-4 box-card" shadow="never">
<template #header> <template #header>
<div class="card-header"> <div class="card-header">
<span class="font-medium">生产环境依赖</span> <span class="font-medium">生产环境依赖</span>
@ -73,7 +73,7 @@ Object.keys(devDependencies).forEach(key => {
</el-descriptions> </el-descriptions>
</el-card> </el-card>
<el-card class="box-card m-4" shadow="never"> <el-card class="m-4 box-card" shadow="never">
<template #header> <template #header>
<div class="card-header"> <div class="card-header">
<span class="font-medium">开发环境依赖</span> <span class="font-medium">开发环境依赖</span>

View File

@ -35,6 +35,14 @@ function onFullscreenClick() {
}); });
} }
function onFullscreenIconClick() {
addDialog({
title: "全屏按钮",
fullscreenIcon: true,
contentRenderer: () => <p>弹框内容-全屏按钮</p>
});
}
function onModalClick() { function onModalClick() {
addDialog({ addDialog({
title: "无背景遮罩层", title: "无背景遮罩层",
@ -394,6 +402,7 @@ function onBeforeSureClick() {
<el-button @click="onBaseClick"> 基本使用 </el-button> <el-button @click="onBaseClick"> 基本使用 </el-button>
<el-button @click="onDraggableClick"> 可拖拽 </el-button> <el-button @click="onDraggableClick"> 可拖拽 </el-button>
<el-button @click="onFullscreenClick"> 全屏 </el-button> <el-button @click="onFullscreenClick"> 全屏 </el-button>
<el-button @click="onFullscreenIconClick"> 全屏按钮 </el-button>
<el-button @click="onModalClick"> 无背景遮罩层 </el-button> <el-button @click="onModalClick"> 无背景遮罩层 </el-button>
<el-button @click="onStyleClick"> 自定义弹出位置 </el-button> <el-button @click="onStyleClick"> 自定义弹出位置 </el-button>
<el-button @click="onoOpenDelayClick"> 延时2秒打开弹框 </el-button> <el-button @click="onoOpenDelayClick"> 延时2秒打开弹框 </el-button>

View File

@ -120,6 +120,7 @@ export function useDept() {
}, },
width: "40%", width: "40%",
draggable: true, draggable: true,
fullscreenIcon: true,
closeOnClickModal: false, closeOnClickModal: false,
contentRenderer: () => h(editForm, { ref: formRef }), contentRenderer: () => h(editForm, { ref: formRef }),
beforeSure: (done, { options }) => { beforeSure: (done, { options }) => {