【sgFloatDialog】自定义组件:浮动弹窗,支持修改尺寸、拖拽位置、最大化、还原、最小化、复位

sgFloatDialog 

<template><div :class="$options.name" v-if="visible" :theme="theme" :size="size" :style="style"><!-- 托盘头部 --><div class="header" ref="header" @dblclick.stop.prevent="dblclickHeader"><div class="left"><div class="title"><i :class="titleIcon" style="margin-right: 5px" /><span>{{ title }}</span></div></div><div class="right" @mousedown.stop><!-- 控制托盘的图标按钮 --><div class="tray-btns"><divclass="icon-btn"v-if="show_rb_btn"v-show="![`rb`, `mn`, `lg`].includes(size)"@dblclick.stop@click.stop="size = `rb`"title="回到原来的位置"><i class="el-icon-bottom-right"></i></div><divclass="icon-btn"v-if="show_mn_btn"v-show="size !== `mn`"@dblclick.stop@click.stop="size = `mn`"title="最小化"><i class="el-icon-minus"></i></div><divclass="icon-btn"v-show="[`mn`, `lg`].includes(size)"@dblclick.stop@click.stop="toMd()"title="还原"><i :class="size === `lg` ? `el-icon-copy-document` : `el-icon-d-caret`"></i></div><divclass="icon-btn"v-show="size !== `lg`"@dblclick.stop@click.stop="size = `lg`"title="全屏"><i class="el-icon-full-screen"></i></div><div class="icon-btn" @dblclick.stop @click.stop="close"><i class="el-icon-close"></i></div></div></div></div><div class="body"><slot /></div><!-- 拖拽移动窗体 --><sgDragMoveref="sgDragMove":data="dragMoveDoms":cursor="{grab: 'default',grabbing: 'default',}"nearPadding="10":disabled="changeSizeStatus"@dragging="draggingMove"mousemoveNearSide/><!-- 拖拽改变窗体尺寸 --><sgDragSizev-if="resizeable":disabled="size === `lg`"@dragStart="changeSizeStatus = true"@dragging="draggingSize"@dragEnd="changeSizeStatus = false":minWidth="minWidth":minHeight="minHeight"/></div>
</template>
<script>
import sgDragMove from "@/vue/components/admin/sgDragMove";
import sgDragSize from "@/vue/components/admin/sgDragSize";
export default {name: "sgFloatDialog",components: {sgDragMove,sgDragSize,},data() {return {form: {},theme: ``, //主题//----------------------------------------titleIcon: `el-icon-question`,title: `浮动窗口标题`,// ----------------------------------------defaultRight: 100, //默认出现的位置defaultBottom: 20, //默认出现的位置defaultWidth: 400, //默认宽度defaultHeight: 500, //默认高度minWidth: 300, //最小宽度minHeight: 50, //最小高度// ----------------------------------------style_bk: null,style: {},visible: false,show_rb_btn: true, //是否显示回到右下角按钮show_mn_btn: true, //是否显示最小化按钮size: ``, //lg全屏最大化 lgl左侧最大化 lgr右侧最大化 md普通 mn最小 rb右下角changeSizeStatus: false, //避免修改尺寸的时候,也在拖拽移动窗体dragMoveDoms: [/* {canDragDom: elementDOM,//可以拖拽的位置元素moveDom: elementDOM,//拖拽同步移动的元素} */], //可以拖拽移动的物体resizeable: true,};},props: ["data", "value"],computed: {},watch: {value: {handler(d) {this.visible = d;},deep: true,immediate: true,},visible(d) {this.$emit("input", d);},data: {handler(newValue, oldValue) {//console.log(`深度监听${this.$options.name}:`, newValue, oldValue);if (Object.keys(newValue || {}).length) {this.form = JSON.parse(JSON.stringify(newValue));this.$g.convertForm2ComponentParam(`theme`, this);this.$g.convertForm2ComponentParam(`titleIcon`, this);this.$g.convertForm2ComponentParam(`title`, this);this.$g.convertForm2ComponentParam(`defaultRight`, this);this.$g.convertForm2ComponentParam(`defaultBottom`, this);this.$g.convertForm2ComponentParam(`defaultWidth`, this);this.$g.convertForm2ComponentParam(`defaultHeight`, this);this.$g.convertForm2ComponentParam(`minWidth`, this);this.$g.convertForm2ComponentParam(`minHeight`, this);this.$g.convertForm2ComponentParam(`resizeable`, this);this.$nextTick(() => {this.$el.style.setProperty("--defaultRight", `${this.defaultRight}px`); //js往css传递局部参数this.$el.style.setProperty("--defaultBottom", `${this.defaultBottom}px`); //js往css传递局部参数this.$el.style.setProperty("--defaultWidth", `${this.defaultWidth}px`); //js往css传递局部参数this.$el.style.setProperty("--defaultHeight", `${this.defaultHeight}px`); //js往css传递局部参数this.$el.style.setProperty("--minWidth", `${this.minWidth}px`); //js往css传递局部参数this.$el.style.setProperty("--minHeight", `${this.minHeight}px`); //js往css传递局部参数this.dragMoveDoms = [{canDragDom: this.$refs.header, //托盘的头部可以拖拽moveDom: this.$el, //拖拽的时候,整个上传列表一起跟随移动},];this.style_bk = {right: `${this.defaultRight}px`,bottom: `${this.defaultBottom}px`,width: `${this.defaultWidth}px`,height: `${this.defaultHeight}px`,};});}},deep: true, //深度监听immediate: true, //立即执行},resizeable: {handler(newValue, oldValue) {newValue === undefined || (this.resizeable = newValue === "" || newValue);},deep: true, //深度监听immediate: true, //立即执行},style: {handler(newValue, oldValue) {if (Object.keys(newValue || {}).length) {let { width, height, left, top } = newValue;width = parseInt(width);height = parseInt(height);left = parseInt(left);top = parseInt(top);if (width <= this.minWidth && height <= this.minHeight) {this.show_mn_btn = false;} else {this.show_mn_btn = true;}let right = innerWidth - left - width;let bottom = innerHeight - top - height;if (right <= this.defaultRight && bottom < this.defaultBottom) {this.show_rb_btn = false;} else {this.show_rb_btn = true;}} else {this.show_mn_btn = true;}},deep: true, //深度监听immediate: true, //立即执行},},created() {},mounted() {},destroyed() {},methods: {toMd() {this.size = null;this.style_bk && (this.style = JSON.parse(JSON.stringify(this.style_bk)));},bkStyle() {this.style && (this.style_bk = JSON.parse(JSON.stringify(this.style)));},fromLgToMd(e) {let { x, y } = e.$event;let style = JSON.parse(JSON.stringify(this.style_bk));let leftPointDis = (x / innerWidth) * parseFloat(style.width); //计算鼠标到左上角定点的距离this.$refs.sgDragMove.setOffset({ x: leftPointDis });},draggingMove(e) {let { x, y } = e.$event;let dis = 5; //吸附屏幕边缘if (y <= dis) {this.size = `lg`; // 拖拽到浏览器顶部} else if (x <= dis) {this.size = `lgl`; // 拖拽到浏览器左侧} else if (x >= innerWidth - dis) {this.size = `lgr`; // 拖拽到浏览器右侧} else {// 拖拽回到浏览器中间if ((this.size || "").includes(`lg`)) {this.fromLgToMd(e);} else {this.style = e.moveDomStyle;this.bkStyle();}this.size = null;}},draggingSize({ style }) {this.style = style;this.bkStyle();this.size = null;},dblclickHeader(d) {switch (this.size) {case "lg":this.size = "md";break;case "mn":this.size = "md";break;case "md":default:this.size = "lg";break;}},// 关闭托盘close() {this.visible = false;this.$emit(`close`, this.style);},},
};
</script>
<style lang="scss" scoped>
.sgFloatDialog {$headerHeight: 40px; //头部高度$defaultRight: var(--defaultRight); //托盘默认距离右下角的位置$defaultBottom: var(--defaultBottom); //托盘默认距离右下角的位置$defaultWidth: var(--defaultWidth); //托盘默认宽度$defaultHeight: var(--defaultHeight); //托盘默认高度$minWidth: var(--minWidth); //托盘最小宽度$minHeight: var(--minHeight); //托盘最小高度// ----------------------------------------transition: none;position: fixed;z-index: 2001; //根据情况自己拿捏(太大了会遮住element的其他弹窗组件),v-loading默认是2000的z-indexuser-select: none;margin: 0;padding: 0;right: 100px;bottom: 20px;width: $defaultWidth;height: $defaultHeight;background-color: white;min-width: $minWidth;min-height: $minHeight;box-shadow: 0 0 35px 0 rgba(0, 0, 0, 0.08);font-size: 14px;// 主题----------------------------------------// 圆角主题&[theme="radius"] {border-radius: 8px;box-shadow: 0 0 35px 0 rgba(0, 0, 0, 0.08), 0px -5px 0 0 #409eff;&::before {content: none;}.header {margin-top: revert;}}// 上传主题&[theme="upload"] {border-radius: 8px;border: 1px solid #172d4533;box-shadow: 0 4px 6px 0 #172d4533;&::before {content: none;}.header {margin-top: revert;}}// 右上角按钮----------------------------------------// 最大化&[size="lg"] {left: 0 !important;top: 0 !important;width: 100vw !important;height: 100vh !important;}// 最大化(左侧)&[size="lgl"] {left: 0 !important;top: 0 !important;width: calc(100vw / 2) !important;height: 100vh !important;}// 最大化(右侧)&[size="lgr"] {left: calc(100vw / 2) !important;top: 0 !important;width: calc(100vw / 2) !important;height: 100vh !important;}// 还原&[size="md"] {}// 最小化&[size="mn"] {left: revert !important;top: revert !important;right: $defaultRight !important;bottom: $defaultBottom !important;width: $minWidth !important;height: $minHeight !important;}// 右下角&[size="rb"] {left: revert !important;top: revert !important;right: $defaultRight !important;bottom: $defaultBottom !important;}&::before {content: "";width: 100%;height: 5px;/*从左往右线性渐变背景*/background: linear-gradient(to right, #409eff, #f56c6c);position: absolute;top: 0;left: 0;width: 100%;}.header {margin-top: 5px;flex-shrink: 0;font-size: 16px;font-weight: bold;width: 100%;height: $headerHeight;box-sizing: border-box;padding: 10px 20px;/*从上往下线性渐变背景*/background: linear-gradient(#409eff11, white);color: #409eff;display: flex;justify-content: space-between;align-items: center;&:hover {background: linear-gradient(#409eff22, white);}.left {display: flex;align-items: center;flex-grow: 1;.title {display: flex;align-items: center;flex-wrap: nowrap;}.icon-btns {display: flex;align-items: center;flex-wrap: nowrap;.icon-btn {cursor: pointer;margin-right: 5px;&:last-of-type {margin-right: 0;}i {pointer-events: none;}&:hover {opacity: 0.618;}}}}.right {display: flex;align-items: center;justify-content: flex-end;flex-shrink: 0;pointer-events: auto;.icon-btn {margin-left: 10px;cursor: pointer;i {pointer-events: none;}&:hover {opacity: 0.618;}&:first-of-type {margin-left: 0;}}.file-btns {margin-left: 10px;display: flex;flex-wrap: nowrap;justify-content: flex-end;box-sizing: border-box;padding: 0 10px;border-right: 1px solid #eee;}.tray-btns {margin-left: 10px;display: flex;flex-wrap: nowrap;justify-content: flex-end;}}}.body {box-sizing: border-box;padding: 20px;padding-top: 0;display: flex;flex-wrap: nowrap;width: 100%;height: calc(100% - #{$headerHeight});}
}
</style>

demo

<template><!-- 指导帮助悬浮弹窗 --><sgFloatDialog:data="data_sgFloatDialog"v-model="show_sgFloatDialog"v-if="show_sgFloatDialog"@close="close"><divstyle="width: 100%;height: 100%;overflow-y: auto;font-size: 16px;text-indent: 32px;line-height: 1.6;"><p>我一路向北,离开有你的季节,你说你好累,已无法再爱上谁。风在山路吹,过往的画面全都是不对,细数惭愧,我伤你几回。</p><p>我想我是太过依赖,在挂电话的刚才,坚持学单纯的小孩,静静看守这份爱,知道不能太依赖,怕你会把我宠坏,你的香味一直徘徊,我舍不得离开。</p><p>缓缓飘落的枫叶像思念,为何挽回要赶在冬天来之前,爱你穿越时间,两行来自秋末的眼泪,让爱渗透了地面我要的只是你在我身边。</p><p>我知道你我都没有错,只是忘了怎么退后,信誓旦旦给的承诺,全被时间扑了空。我知道我们都没有错,只是放手会比较好过,最美的爱情回忆里待续。</p></div></sgFloatDialog>
</template>
<script>
import sgFloatDialog from "@/vue/components/admin/sgFloatDialog";export default {components: { sgFloatDialog },data() {return {data_sgFloatDialog: {// theme: `radius`,//主题titleIcon: `el-icon-info`,title: `标题`,defaultRight: 10,defaultBottom: 10,defaultWidth: 400,defaultHeight: 600,},show_sgFloatDialog: true,};},methods: {close(d) {// console.log(``, d);},},
};
</script>

依赖

【sgDragMove】自定义组件:自定义拖拽组件,仅支持拖拽、设置吸附屏幕边界距离。_自定义拖拽位置-CSDN博客文章浏览阅读245次。sgDragMove是一个支持拖拽元素并能吸附到屏幕边界的Vue.js组件。它允许用户自定义吸附距离,可以设置拖拽行为是否禁用,以及停靠边界距离。组件在拖拽过程中提供了半透明效果,并能在不同阶段监听和处理鼠标事件以实现拖拽、吸附和停靠功能。 https://blog.csdn.net/qq_37860634/article/details/131721634【sgDragSize】自定义组件:自定义拖拽修改DIV尺寸组件,适用于窗体大小调整_div拖拽调整大小-CSDN博客文章浏览阅读505次。核心原理就是在四条边、四个顶点加上透明的div,给不同方向提供按下移动鼠标监听 ,对应计算宽度高度、坐标变化。_div拖拽调整大小 https://blog.csdn.net/qq_37860634/article/details/132347222

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/37140.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java后端开发技术详解

Java作为一门成熟的编程语言&#xff0c;已广泛应用于后端开发领域。其强大的生态系统和广泛的支持库使得Java成为许多企业和开发者的首选后端开发语言。随着云计算、微服务架构和大数据技术的兴起&#xff0c;Java后端开发的技术栈也不断演进。本文将详细介绍Java后端开发的核…

搭建ISCSI传输的配置与管理

前提是&#xff1a; windows server2019设置成桥接模式&#xff0c;因为要让虚拟机和主机设置成一个网段&#xff0c;才能通过网络进行新建虚拟磁盘。 1.添加ISCSI角色 安装位置 选择文件和存储服务----------文件和iscsl 服务------------iscsl目标服务器 2.右上角点击任务&a…

晶艺代理,100V3.5A高耐压LA1823完全替换MP9487--启烨科技有限公司

晶艺品牌LA1823是异步降压转换器&#xff0c;COT控制&#xff0c;PFM工作模式, 150KHz/ 250KHz/ 450KHz &#xff0c;开关频率可调节&#xff0c;输入电压4.5~100V&#xff0c;2A平均电流&#xff0c;峰值电流3.5A&#xff0c;采用ESOP8封装。 晶艺LA1823的特性&#xff1a; 4.…

2024年消费者权益数据分析

&#x1f4c5; 2024年315消费者权益数据分析 数据见&#xff1a;https://mp.weixin.qq.com/s/eV5GoionxhGpw7PunhOVnQ 一、引言 在数字化时代&#xff0c;消费者维权数据对于市场监管、商家诚信和行业发展具有重要价值。本文基于 2024年315平台线上投诉数据&#xff0c;采用数…

jmeter吞吐量控制器-Throughput Controller

jmeter吞吐量控制器-Throughput Controller 新增吞吐量控制器名词解释测试场景场景1&#xff1a;场景2&#xff1a;场景3场景4场景5场景6场景7场景8 测试结论 根据百分比执行不同的接口测试场景测试结果 新增吞吐量控制器 名词解释 Based on: Total Executions(总执行数)/Perc…

微服务》》Kubernetes (K8S) 集群配置网络》》Calico

嘻嘻嘻 以Calico 为例子 Calico官网 官网上有安装Calico插件的步骤 步骤 要在主节点 主节点 主节点 执行 kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.2/manifests/tigera-operator.yaml kubectl create -f https://raw.githubuse…

蓝桥杯关于栈这个数据结构的一个算法题目

文章目录 1.题目概述解释2.思路分析3.代码解析 1.题目概述解释 找出来这个字符串里面重复出现的字符&#xff0c;类似于这个消消乐的游戏&#xff1b; 示例一里面的这个bb是连续的并且是一样的这个字符&#xff0c;因此删除bb&#xff0c;删除之后发现这个aa有一次相邻了&…

打破煤矿通信屏障,无线系统赋能生产安全与智能进阶

项目背景 在煤矿行业智能化转型的浪潮中&#xff0c;七台河矿业局积极回应国家煤矿智能化建设的号召&#xff0c;采取了具有前瞻性的战略举措——在七台河地区的煤矿部署了“井上井下”无线覆盖与广播一体化系统。此举旨在消除井上与井下之间的通信障碍&#xff0c;加强矿业局与…

基于CNN的FashionMNIST数据集识别4——GoogleNet模型

源码 import torch from torch import nn from torchsummary import summaryclass Inception(nn.Module):def __init__(self, in_channels, c1, c2, c3, c4):super().__init__()self.ReLu nn.ReLU()#路径1self.p1_1 nn.Conv2d(in_channelsin_channels, out_channelsc1, kern…

面试题精选《剑指Offer》:JVM类加载机制与Spring设计哲学深度剖析-大厂必考

一、JVM类加载核心机制 &#x1f525; 问题5&#xff1a;类从编译到执行的全链路过程 完整生命周期流程图 关键技术拆解 编译阶段 查看字节码指令&#xff1a;javap -v Robot.class 常量池结构解析&#xff08;CONSTANT_Class_info等&#xff09; 类加载阶段 // 手动加载…

(2025|ICLR|华南理工,任务对齐,缓解灾难性遗忘,底层模型冻结和训练早停)语言模型持续学习中的虚假遗忘

Spurious Forgetting in Continual Learning of Language Models 目录 1. 引言 2. 动机&#xff1a;关于虚假遗忘的初步实验 3. 深入探讨虚假遗忘 3.1 受控实验设置 3.2 从性能角度分析 3.3 从损失景观角度分析 3.4 从模型权重角度分析 3.5 从特征角度分析 3.6 结论 …

【css酷炫效果】纯CSS实现火焰文字特效

【css酷炫效果】纯CSS实现火焰文字特效 缘创作背景html结构css样式完整代码基础版进阶版(冰霜版) 效果图 想直接拿走的老板&#xff0c;链接放在这里&#xff1a;https://download.csdn.net/download/u011561335/90492005 缘 创作随缘&#xff0c;不定时更新。 创作背景 刚…

专访LayaAir引擎最有价值专家-施杨

在 LayaAir 引擎的资源商店中&#xff0c;许多开发者都会注意到一个熟悉的名字——“射手座”。他不仅贡献了大量高质量的 Shader 资源&#xff0c;让一些开发者通过他的作品了解到 LayaAir 引擎在 3D 视觉效果上的更多可能&#xff0c;也让大家能够以低成本直接学习并应用这些…

大模型详细配置

Transformer结构 目前主力大模型都是基于Transformer的&#xff0c;以下是Transformer的具体架构 它由编码器(Encoder)以及解码器(Decoder)组成&#xff0c;前者主要负责对输入数据进行理解&#xff0c;将每个输入 词元都编码成一个上下文语义相关的表示向量&#xff1b;后者…

鸿蒙NEXT项目实战-百得知识库04

代码仓地址&#xff0c;大家记得点个star IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点&#xff1a; 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三…

Python数据可视化实战:从基础图表到高级分析

Python数据可视化实战&#xff1a;从基础图表到高级分析 数据可视化是数据分析的重要环节&#xff0c;通过直观的图表可以快速洞察数据规律。本文将通过5个实际案例&#xff0c;手把手教你使用Python的Matplotlib库完成各类数据可视化任务&#xff0c;涵盖条形图、堆积面积图、…

修改原生的<input type=“datetime-local“>样式

效果 基础样式 <input type"datetime-local" class"custom-datetime">input[type"datetime-local"] {/* 重置默认样式 */-webkit-appearance: none;-moz-appearance: none;appearance: none; // 禁用浏览器默认样式/* 自定义基础样式 */w…

scrapy入门(深入)

Scrapy框架简介 Scrapy是:由Python语言开发的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据&#xff0c;只需要实现少量的代码&#xff0c;就能够快速的抓取。 新建项目 (scrapy startproject xxx)&#xff1a;新建一个新的…

fetch,ajax,axios的区别以及使用

fetch,ajax,axios这些都是发起前端请求的工具&#xff0c;除了这些外还有jquery的$.ajax。ajax和$.ajax都是基于XMLHttpRequest。 介绍下XMLHttpRequest XMLHttpRequest是一种在浏览器中用于与服务器进行异步通信的对象&#xff0c;它是实现 AJAX&#xff08;Asynchronous Ja…

微信小程序的业务域名配置(通过ingress网关的注解)

一、背景 微信小程序的业务域名配置&#xff08;通过kong网关的pre-function配置&#xff09;是依靠kong实现&#xff0c;本文将通过ingress网关实现。 而我们的服务是部署于阿里云K8S容器&#xff0c;当然内核与ingress无异。 找到k8s–>网络–>路由 二、ingress注解 …