Vue3对话框(Dialog)
Vue2对话框(Dialog)
可自定义设置以下属性:
-
标题(title),类型:string | slot,默认 '提示'
-
内容(content),类型:string | slot,默认 ''
-
宽度(width),类型:number,默认 640px
-
高度(height),类型:number,默认 480px
-
是否允许切换全屏,允许后右上角会出现一个按钮(switchFullscreen),类型:boolean,默认 false
-
取消按钮文字(cancelText),类型:string,默认 '取消'
-
确认按钮文字(okText),类型:string,默认 '确认'
-
是否显示底部按钮(footer),类型:boolean,默认 false
-
是否水平垂直居中(center),类型:boolean,默认 true,(false时是固定高度水平居中)
-
固定高度水平居中时,距顶部高度(top),类型:number,默认 100px
-
加载中(loading),类型:boolean,默认 false
-
对话框是否可见(visible),类型:boolean,默认 false
效果如下图:(整体样式模仿ant-design-vue Modal,同时阴影覆盖浏览器窗口)
①创建对话框组件Dialog.vue:
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
const props = defineProps({title: { // 标题 string | slottype: String,default: '提示'},content: { // 内容 string | slottype: String,default: ''},width: { // 宽度,默认640type: Number,default: 640},height: { // 高度,默认480type: Number,default: 480},switchFullscreen: { // 是否允许切换全屏,允许后右上角会出现一个按钮type: Boolean,default: false},cancelText: { // 取消按钮文字type: String,default: '取消'},okText: { // 确认按钮文字type: String,default: '确定'},footer: { // 是否显示底部按钮,默认不显示type: Boolean,default: false},center: { // 水平垂直居中:true 固定高度水平居中:falsetype: Boolean,default: true},top: { // 固定高度水平居中时,距顶部高度type: Number,default: 100},loading: { // 加载中type: Boolean,default: false},visible: { // 对话框是否可见type: Boolean,default: false}})const fullScreen = ref(false)
const dialogWidth = computed(() => {if (fullScreen.value) {return '100%'} else {return props.width + 'px'}})
const dialogHeight = computed(() => {if (fullScreen.value) {return '100vh'} else {return props.height + 'px'}})
watch(() => props.visible, (to) => {if (!to) { // 重置全屏显示fullScreen.value = false}
})
const emits = defineEmits(['close', 'cancel', 'ok'])
function onBlur () {if (!props.loading) {emits('close')}
}
function onFullScreen () {fullScreen.value = !fullScreen.value
}
function onClose () {emits('close')
}
function onCancel () {emits('cancel')
}
function onConfirm () {emits('ok')
}
</script>
<template><Transition><div class="m-dialog-mask" v-show="visible" @click.self="onBlur"><div :class="['m-dialog', center ? 'relative-hv-center' : 'top-center']" :style="`width: ${dialogWidth}; height: ${dialogHeight}; top: ${!center ? top + 'px':'50%'}`"><div class="m-dialog-content" :class="{loading: loading}"><div class="m-spin-dot" v-show="loading"><span class="u-dot-item"></span><span class="u-dot-item"></span><span class="u-dot-item"></span><span class="u-dot-item"></span></div><svg @click="onFullScreen" v-show="!fullScreen&&switchFullscreen" class="u-screen" viewBox="64 64 896 896" data-icon="fullscreen" aria-hidden="true" focusable="false"><path d="M290 236.4l43.9-43.9a8.01 8.01 0 0 0-4.7-13.6L169 160c-5.1-.6-9.5 3.7-8.9 8.9L179 329.1c.8 6.6 8.9 9.4 13.6 4.7l43.7-43.7L370 423.7c3.1 3.1 8.2 3.1 11.3 0l42.4-42.3c3.1-3.1 3.1-8.2 0-11.3L290 236.4zm352.7 187.3c3.1 3.1 8.2 3.1 11.3 0l133.7-133.6 43.7 43.7a8.01 8.01 0 0 0 13.6-4.7L863.9 169c.6-5.1-3.7-9.5-8.9-8.9L694.8 179c-6.6.8-9.4 8.9-4.7 13.6l43.9 43.9L600.3 370a8.03 8.03 0 0 0 0 11.3l42.4 42.4zM845 694.9c-.8-6.6-8.9-9.4-13.6-4.7l-43.7 43.7L654 600.3a8.03 8.03 0 0 0-11.3 0l-42.4 42.3a8.03 8.03 0 0 0 0 11.3L734 787.6l-43.9 43.9a8.01 8.01 0 0 0 4.7 13.6L855 864c5.1.6 9.5-3.7 8.9-8.9L845 694.9zm-463.7-94.6a8.03 8.03 0 0 0-11.3 0L236.3 733.9l-43.7-43.7a8.01 8.01 0 0 0-13.6 4.7L160.1 855c-.6 5.1 3.7 9.5 8.9 8.9L329.2 845c6.6-.8 9.4-8.9 4.7-13.6L290 787.6 423.7 654c3.1-3.1 3.1-8.2 0-11.3l-42.4-42.4z"></path></svg><svg @click="onFullScreen" v-show="fullScreen&&switchFullscreen" class="u-screen" viewBox="64 64 896 896" data-icon="fullscreen-exit" aria-hidden="true" focusable="false"><path d="M391 240.9c-.8-6.6-8.9-9.4-13.6-4.7l-43.7 43.7L200 146.3a8.03 8.03 0 0 0-11.3 0l-42.4 42.3a8.03 8.03 0 0 0 0 11.3L280 333.6l-43.9 43.9a8.01 8.01 0 0 0 4.7 13.6L401 410c5.1.6 9.5-3.7 8.9-8.9L391 240.9zm10.1 373.2L240.8 633c-6.6.8-9.4 8.9-4.7 13.6l43.9 43.9L146.3 824a8.03 8.03 0 0 0 0 11.3l42.4 42.3c3.1 3.1 8.2 3.1 11.3 0L333.7 744l43.7 43.7A8.01 8.01 0 0 0 391 783l18.9-160.1c.6-5.1-3.7-9.4-8.8-8.8zm221.8-204.2L783.2 391c6.6-.8 9.4-8.9 4.7-13.6L744 333.6 877.7 200c3.1-3.1 3.1-8.2 0-11.3l-42.4-42.3a8.03 8.03 0 0 0-11.3 0L690.3 279.9l-43.7-43.7a8.01 8.01 0 0 0-13.6 4.7L614.1 401c-.6 5.2 3.7 9.5 8.8 8.9zM744 690.4l43.9-43.9a8.01 8.01 0 0 0-4.7-13.6L623 614c-5.1-.6-9.5 3.7-8.9 8.9L633 783.1c.8 6.6 8.9 9.4 13.6 4.7l43.7-43.7L824 877.7c3.1 3.1 8.2 3.1 11.3 0l42.4-42.3c3.1-3.1 3.1-8.2 0-11.3L744 690.4z"></path></svg><svg @click="onClose" class="u-close" viewBox="64 64 896 896" data-icon="close" aria-hidden="true" focusable="false"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 0 0 203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"></path></svg><div class="m-dialog-header"><slot name="title"><div class="u-head">{{ title }}</div></slot></div><div class="m-dialog-body" :style="`height: calc(${dialogHeight} - ${footer ? '158px':'103px'});`"><slot>{{ content }}</slot></div><div class="m-dialog-footer" v-show="footer"><button class="u-cancel" @click="onCancel">{{ cancelText }}</button><button class="u-confirm" @click="onConfirm">{{ okText }}</button></div></div></div></div></Transition>
</template>
<style lang="less" scoped>
.v-enter-active, .v-leave-active {transition: opacity 0.3s ease;
}
.v-enter-from, .v-leave-to {opacity: 0;
}
.flex-hv-center { // 水平垂直居中方法①:弹性布局,随内容增大高度,并自适应水平垂直居中display: flex;justify-content: center;align-items: center;
}
.relative-hv-center { // 水平垂直居中方法②:相对定位,随内容增大高度,并自适应水平垂直居中position: relative;top: 50%;transform: translateY(-50%);-ms-transform: translateY(-50%);; /* IE 9 */-webkit-transform: translateY(-50%); /* Safari and Chrome */
}
.top-center { // 相对定位,固定高度,始终距离视图顶端100pxposition: relative;// top: 100px;
}
.m-dialog-mask {position: fixed;top: 0;right: 0;bottom: 0;left: 0;width: 100%;height: 100%;z-index: 10000;background: rgba(0,0,0,0.45);.m-dialog {margin: 0 auto;transition: all .3s ease;.m-spin-dot { // 绝对定位,并设置水平垂直居中position: absolute;display: inline-block;right: 0;left: 0;top: 0;bottom: 0;margin: auto;width: 24px;height: 24px;transform: rotate(45deg);-ms-transform: rotate(45deg); /* Internet Explorer */-moz-transform: rotate(45deg); /* Firefox */-webkit-transform: rotate(45deg); /* Safari 和 Chrome */-o-transform: rotate(45deg); /* Opera */animation: rotate 1.2s linear infinite;-webkit-animation: rotate 1.2s linear infinite;@keyframes rotate {100% {transform: rotate(405deg);}}.u-dot-item { // 单个圆点样式position: absolute;width: 8px;height: 8px;background: @themeColor;border-radius: 50%;opacity: .3;animation: spinMove 1s linear infinite alternate;-webkit-animation: spinMove 1s linear infinite alternate;@keyframes spinMove {100% {opacity: 1;}}}.u-dot-item:first-child {top: 0;left: 0;}.u-dot-item:nth-child(2) {top: 0;right: 0;animation-delay: .4s;-webkit-animation-delay: .4s;}.u-dot-item:nth-child(3) {bottom: 0;right: 0;animation-delay: .8s;-webkit-animation-delay: .8s;}.u-dot-item:last-child {bottom: 0;left: 0;animation-delay: 1.2s;-webkit-animation-delay: 1.2s;}}.loading { // 加载过程背景虚化background: rgb(248, 248, 248) !important;pointer-events: none; // 屏蔽鼠标事件}.m-dialog-content {position: relative;background: #fff;border-radius: 4px;box-shadow: 0 4px 12px rgba(0,0,0,.1);.u-screen {.u-close();right: 64px;}.u-close {width: 16px;height: 16px;position: absolute;top: 19px;right: 24px;fill: rgba(0,0,0,.45);cursor: pointer;transition: fill .3s;&:hover {fill: rgba(0,0,0,.75);}}.m-dialog-header {height: 22px;padding: 16px 24px;color: rgba(0,0,0,.65);border-radius: 4px 4px 0 0;border-bottom: 1px solid #e8e8e8;.u-head {margin: 0;color: rgba(0,0,0,.85);font-weight: 500;font-size: 16px;line-height: 22px;word-wrap: break-word;}}.m-dialog-body {padding: 24px;font-size: 16px;line-height: 1.5;word-wrap: break-word;overflow: auto;transition: all .3s;}.m-dialog-footer {padding: 10px 16px;text-align: right;border-top: 1px solid #e8e8e8;.u-cancel {height: 32px;line-height: 32px;padding: 0 15px;font-size: 16px;border-radius: 4px;color: rgba(0,0,0,.65);background: #fff;border: 1px solid #d9d9d9;cursor: pointer;transition: all .3s cubic-bezier(.645,.045,.355,1);&:hover {color: fade(@themeColor, 80%);border-color: fade(@themeColor, 80%);}&:focus {color: shade(@themeColor, 12%);border-color: shade(@themeColor, 12%);}}.u-confirm {margin-left: 8px;height: 32px;line-height: 32px;padding: 0 15px;font-size: 16px;border-radius: 4px;background: @themeColor;border: 1px solid @themeColor;color: #fff;transition: all .3s cubic-bezier(.645,.045,.355,1);cursor: pointer;&:hover {background: fade(@themeColor, 80%);border-color: fade(@themeColor, 80%);}&:focus {background: shade(@themeColor, 12%);border-color: shade(@themeColor, 12%);}}}}}
}
</style>
②在要使用的页面引入:
<script setup lang="ts">
import { Dialog } from './Dialog.vue'
import { ref } from 'vue'
import { rafTimeout } from '../../packages'const center = ref(true)
const footer = ref(false)
const loading = ref(false)
const visible = ref(false)
const title = ref('Dialog Title')
const content = ref('Content of the modal ...')
function showDialog (info: string) {footer.value = falsecenter.value = truecontent.value = infovisible.value = true
}
function showFooterDialog (info: string) {footer.value = truecenter.value = truecontent.value = infovisible.value = true
}
function showCenterDialog (info: string) {center.value = truecontent.value = infovisible.value = true
}
function showFixDialog (info: string) {center.value = falsecontent.value = infovisible.value = true
}
function onClose () { // 关闭回调visible.value = false
}
function onCancel () { // “取消”按钮回调visible.value = false
}
function onConfirm () { // “确定”,“知道了”按钮回调loading.value = true // 开启加载状态rafTimeout(() => {visible.value = falseloading.value = false}, 500)
}
</script>
<template><div><h2 class="mb10">Dialog 对话框基本使用</h2><Button class="mr30" @click="showDialog('Some descriptions ...')">默认对话框</Button><Button class="mr30" @click="showFooterDialog('Some descriptions ...')">有底部按钮的对话框</Button><Button class="mr30" @click="showCenterDialog('Some descriptions ...')">水平垂直居中对话框</Button><Button class="mr30" @click="showFixDialog('Some descriptions ...')">高度固定对话框</Button><Dialog:title="title":width="720":height="480":content="content":footer="footer"cancelText="取消"okText="确认"switchFullscreen@close="onClose"@cancel="onCancel"@ok="onConfirm":center="center":top="100":loading="loading":visible="visible"><template #title><p class="u-title">Title</p></template><p>Bla bla ...</p><p>Bla bla ...</p><p>Bla bla ...</p></Dialog></div>
</template>
<style lang="less" scoped>
.u-title {font-size: 16px;
}
</style>
相关文章:

Vue3对话框(Dialog)
Vue2对话框(Dialog) 可自定义设置以下属性: 标题(title),类型:string | slot,默认 提示 内容(content),类型:string | slot…...

【深度强化学习】(5) DDPG 模型解析,附Pytorch完整代码
大家好,今天和各位分享一下深度确定性策略梯度算法 (Deterministic Policy Gradient,DDPG)。并基于 OpenAI 的 gym 环境完成一个小游戏。完整代码在我的 GitHub 中获得: https://github.com/LiSir-HIT/Reinforcement-Learning/tree/main/Mod…...
unity,Color.Lerp函数
介绍 Color.Lerp函数是Unity引擎中的一个静态函数,用于在两个颜色值之间进行线性插值,从而实现颜色渐变效果 方法 Color.Lerp函数是Unity引擎中的一个静态函数,用于在两个颜色值之间进行线性插值,从而实现颜色渐变效果。该函数的…...

洛谷P8799 [蓝桥杯 2022 国 B] 齿轮 C语言/C++
[蓝桥杯 2022 国 B] 齿轮 题目描述 这天,小明在组装齿轮。 他一共有 nnn 个齿轮,第 iii 个齿轮的半径为 rir_{i}ri, 他需要把这 nnn 个齿轮按一定顺序从左到右组装起来,这样最左边的齿轮转起来之后,可以传递到最右边的齿轮&a…...

景区在线售票系统功能开发介绍
目前游客线上订票已经普及,景区开通线上购票渠道,方便游客购票,对于还没有开通线上购票的景区来说,需要提前了解一下景区线上售票系统的一些功能,下面给大家详细介绍一下景区在线售票需要哪些功能。 1、在线售票 包含门…...
webService的底层调用方式
webservice中采用协议Http,是指什么意思 WebService使用的是 SOAP (Simple Object Access Protocol)协议 Soap协议只是用来封装消息用的。封装后的消息你可以通过各种已有的协议来传输,比如http,tcp/ip,smtp,等等,你甚至还一次用自定义的协议…...

关于文件的一些小知识下
🍍个人主页🍍:🔜勇敢的小牛儿🚩 🔱推荐专栏🔱:C语言知识点 ⚠️座右铭⚠️:敢于尝试才有机会 🐒今日鸡汤🐒: 你受的苦 吃的亏 担的责 扛的罪 忍的…...

使用Cheat Engine与DnSpy破解Unity游戏
题目连接: https://play.picoctf.org/practice/challenge/361?originalEvent72&page3我们是windows系统,所以点击windows game下载游戏 双击运行pico.exe 屏幕上方的一串英文是叫我们找flag,我在这个小地图里走来走去也没flagÿ…...

溯源取证-内存取证基础篇
使用工具: volatility_2.6_lin64_standalone 镜像文件: CYBERDEF-567078-20230213-171333.raw 使用环境: kali linux 2022.02 我们只有一个RAW映像文件,如何从该映像文件中提取出我们想要的东西呢? 1.Which volatili…...

Leetcode.100 相同的树
题目链接 Leetcode.100 相同的树 easy 题目描述 给你两棵二叉树的根节点 p和 q,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 示例 1: 输入:p [1,2,3…...
每个程序员都应该知道的8大算法
在编程开发中,算法是用于解决特定问题或完成特定任务的一组指令或过程。算法可以用任何编程语言表示,可以像一系列基本操作一样简单,也可以像涉及不同数据结构和逻辑的多步骤过程一样复杂。 算法的主要目标是接收输入、处理它并提供预期的输…...

Nestjs实战超干货-概况-模块-Modules
模块 模块就是一个声明了装饰器Module()的类。装饰器Module()提供了元数据,以便让Nest组织应用程序结构。 每个应用程序至少有一个模块,即根模块。根模块是 Nest 用来构建应用程序图的起点,应用程序图是 Nest 用来解析模块和提供者关系和依赖…...
template
模板 模板注意事项 模板的函数体和声明一定要在一起,即放在同一个.h文件中,而不能将其分开到cpp和h文件中模板的编译技巧就是尽量多编译,模板很难查找错误模板的报错一般只有第一行有作用模板指定类型从左到右依次指定 模板推导 #pragma #…...

innovus中时序路径debug及命令使用详解?
写在前面:发现place结果所有与outport相关的timing check都找不到? 刚开始怀疑是sdc约束问题,check了input sdc文件及enc.dat/mmmc/mode/func.sdc 看一下是否设置了set_false_path.当然也可以用命令报出来: report_timing -unconstrained …...

C语言爱心代码大全集—会Ctrl+C就可以表白了
一、C语言爱心代码大全,会CtrlC就可以表白了! 博主整理了一个C语言爱心代码大全,里面有C语言爱心代码会动的动态效果和C语言爱心代码大全静态效果,只需复制粘贴就可以用啦! 1、动态C语言爱心代码效果图如下ÿ…...

python+vue+django耕地信息管理系统的设计与实现
基普通用户模块含有个人中心、耕地信息管理、转让许可申请管理、租赁许可申请管理等功能;普通管理员模块含有个人中心、用户管理、公示公告管理、耕地信息管理、耕地信息统计、转让许可申请管理、租赁许可申请管理、转让协议管理、租赁协议管理等功能;管…...

【云原生】Dockerfile制作WordPress镜像,实现compose编排部署
文章目录👹 关于作者前言环境准备目录结构dockerfile制作镜像yum 脚本Dockerfile-mariadb 镜像Dockerfile-service 镜像docker compose 编排提升✊ 最后👹 关于作者 大家好,我是秋意临。 😈 CSDN作者主页 😎 博客主页…...

五款好用又有趣的WIN10软件推荐
如果你想让你的电脑使用更方便、更有趣、更专业,那么你一定要看看这篇文章,因为我要给你推荐五款好用又有趣的WIN10软件 1.全局搜索——火柴 火柴是一款全局搜索软件,可以让你快速找到你想要的文件、程序、网页等,只需按下AltSp…...
朴素贝叶斯算法
# -*-coding:utf-8-*- """ Author: sunchang Desc: 代码4-7 朴素贝叶斯实现对异常账户检测 """ import numpy as np class NaiveBayesian: def __init__(self, alpha): self.classP dict() self.classP_f…...

【常见CSS扫盲雪碧图】从源码细看CSS雪碧图原理及实现,千字详解【附源码demo下载】
【写在前面】其实估计很多人都听过雪碧图,或者是CSS-Sprite,在很多门户网站就会经常有用到的,之所有引出雪碧图这个概念还得从前端加载多个图片时候页面闪了一下说起,这样给人的视觉效果体验很差,也就借此机会和大家说…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...

图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...