项目中很多时候需要弹出框可以拖动并且可最大化,el-dialog是不满足的,这边采用指令的方式进行拓展。

先来个效果图:

首先来个v-darg指令:

 1 import Vue from 'vue'
2
3 Vue.directive('alterELDialogMarginTop', {
4 inserted(el, binding, vnode) {
5 el.firstElementChild.style.marginTop = binding.value + 'px'
6 }
7 })
8
9 Vue.directive('alterELDialogMarginLeft', {
10 inserted(el, binding, vnode) {
11 el.firstElementChild.style.marginLeft = binding.value + 'px'
12 }
13 })
14
15 Vue.directive('drag', {
16 inserted(el, binding, vnode) {
17 let odiv = el.getElementsByTagName('div')[0];
18 let headerDiv = odiv.getElementsByTagName('div')[0];
19 const deepHeader = headerDiv.querySelector('header');
20 const flag = elementContains(headerDiv, deepHeader); //兼容dialog&&drawer
21 if(flag) {
22 headerDiv = deepHeader;
23 }
24 headerDiv.onmousedown = e => {
25 // document.body.style.userSelect = 'none';
26 // document.body.style.webkitUserSelect = 'none';
27 // document.body.style.msUserSelect = 'none';
28 // document.body.style.mozUserSelect = 'none';
29 // let odiv = el.getElementsByTagName('div')[0];
30 let disX = e.clientX - odiv.offsetLeft;
31 let disY = e.clientY - odiv.offsetTop;
32 document.onmousemove = e => {
33 let left = e.clientX - disX;
34 let top = e.clientY - disY;
35 odiv.style.marginLeft = left + 'px';
36 odiv.style.marginTop = top + 'px';
37 };
38 document.onmouseup = e => {
39 document.onmousemove = null;
40 document.onmouseup = null;
41 // document.body.style.userSelect = 'auto';
42 // document.body.style.webkitUserSelect = 'auto';
43 // document.body.style.msUserSelect = 'auto';
44 // document.body.style.mozUserSelect = 'auto';
45 };
46 };
47 }
48 })
49
50 const elementContains = (parent, child) => parent !== child && parent.contains(child);

再来个v-fullscreen指令:

 1 import Vue from 'vue'
2
3 function handleFullScreen(dialog, isFullScreen, marginTop, width) {
4 if (!dialog) return false
5 if (isFullScreen) {
6 dialog.style.marginTop = '0'
7 dialog.style.marginLeft = '0'
8 dialog.style.position = 'absolute'
9 dialog.style.top = '0px'
10 dialog.style.bottom = '0px'
11 dialog.style.left = '0px'
12 dialog.style.width = '100%'
13 } else {
14 // dialog.style.marginTop = marginTop
15 dialog.style.margin = '0 auto'
16 dialog.style.width = width
17 dialog.style.position = 'relative'
18 }
19 }
20
21 Vue.directive('fullScreen', {
22 bind(el, binding, vnode) {
23 let isFullScreen = false
24
25 const dialog = el.querySelector('.el-dialog')
26 const header = el.querySelector('.el-dialog__header')
27 if (!header || !dialog || !vnode) return
28 header.style.paddingRight = '43px'
29 header.style.boxShadow = '0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)'
30 const {
31 width,
32 top
33 } = vnode.componentInstance
34
35 const fullScreenBtn = document.createElement('button')
36 fullScreenBtn.type = 'button'
37 fullScreenBtn.style =
38 'padding:0;background: 0 0;border:0;outline:0;cursor:pointer;font-size:17px;top:14px;right:38px;position:absolute;color:white;'
39
40 const fullScreenIcon = document.createElement('i')
41 fullScreenIcon.className = 'el-icon el-icon-full-screen'
42 fullScreenBtn.append(fullScreenIcon)
43
44 fullScreenBtn.addEventListener('click', () => {
45 isFullScreen = !isFullScreen
46 handleFullScreen(dialog, isFullScreen, top, width)
47 return false
48 })
49
50 header.append(fullScreenBtn)
51
52 header.addEventListener('dblclick', () => {
53 isFullScreen = !isFullScreen
54 handleFullScreen(dialog, isFullScreen, top, width)
55 return false
56 })
57 }
58 })

集成el-dialog,(这个封装里面稍微做了一点对于移动端和pc端的尺寸响应,不需要可以去掉):

  1 <template>
2 <el-dialog
3 v-drag
4 v-fullScreen
5 :title="title"
6 :visible="visible"
7 :show-close="showClose"
8 :close-on-click-modal="closeOnClickModal"
9 :append-to-body="true"
10 close-on-press-escape
11 :modal="modal"
12 :width="`${device === mobile ? 100 : width}%`"
13 :top="`${device === mobile ? 0 : top}px`"
14 v-if="visible"
15 @close="closeDialog"
16 >
17 <div><slot name="title"></slot></div>
18 <div><slot></slot></div>
19 <div slot="footer"><slot name="footer"></slot></div>
20 </el-dialog>
21 </template>
22
23 <script>
24 // :center="!!+(`${device === mobile ? false : true}`)"
25
26 const { body } = document;
27 const WIDTH = 992; // refer to Bootstrap's responsive design
28 const DESKTOP = 'desktop';
29 const MOBILE = 'mobile';
30
31 export default {
32 name: 'LiloResponsiveDialog',
33 props: {
34 title: {
35 type: String,
36 default: ''
37 },
38 width: {
39 type: [Number, String],
40 default: 50
41 },
42 top: {
43 type: [Number, String],
44 default: 54
45 },
46 visible: {
47 type: Boolean,
48 default: false
49 },
50 showClose: {
51 type: Boolean,
52 default: true
53 },
54 closeOnClickModal: {
55 type: Boolean,
56 default: false
57 },
58 modal: {
59 type: Boolean,
60 default: true
61 }
62 },
63 data() {
64 return {
65 device: DESKTOP,
66 mobile: MOBILE
67 };
68 },
69 beforeMount() {
70 window.addEventListener('resize', this.$_resizeHandler);
71 },
72 beforeDestroy() {
73 window.removeEventListener('resize', this.$_resizeHandler);
74 },
75 mounted() {
76 const isMobile = this.$_isMobile();
77 if (isMobile) {
78 this.device = 'mobile';
79 }
80 },
81 methods: {
82 $_isMobile() {
83 const rect = body.getBoundingClientRect();
84 return rect.width - 1 < WIDTH;
85 },
86 $_resizeHandler() {
87 if (!document.hidden) {
88 const isMobile = this.$_isMobile();
89 this.device = isMobile ? MOBILE : DESKTOP;
90 }
91 },
92 closeDialog() {
93 this.$emit('update:visible', false);
94 this.$emit('close');
95 }
96 }
97 };
98 </script>
99
100 <style></style>

最后直接调用LiloResponsiveDialog组件即可,而我这里是做成了插件。

1 import ResponsiveDialog from './src/main';
2
3 /* istanbul ignore next */
4 ResponsiveDialog.install = function(Vue) {
5 Vue.component(ResponsiveDialog.name, ResponsiveDialog);
6 };
7
8 export default ResponsiveDialog;

Vue【原创】整合el-dialog,可拖动可全屏最大化弹出框的更多相关文章

  1. 基于Vue.js PC桌面端弹出框组件|vue自定义弹层组件|vue模态框

    vue.js构建的轻量级PC网页端交互式弹层组件VLayer. 前段时间有分享过一个vue移动端弹窗组件,今天给大家分享一个最近开发的vue pc端弹出层组件. VLayer 一款集Alert.Dia ...

  2. elementUI vue 页面加载的时候页面出现了黑字 页面优化处理 按钮弹出框文字

    elementUI 页面如果需要加载很多东西的时候, 自己定义的按钮或者弹出框dialog的文字就会显示在页面上, 一闪而过, 因此需要优化一下, elementUI 提供的loading有遮罩层, ...

  3. vue--vant组件库Dialog弹出框

    安装vant UI框架: cnpm install vant –-save-dev 导入组件-在main.js里: import Vant from 'vant'; import'vant/lib/v ...

  4. WPF无边框拖动、全屏、缩放

    原文:WPF无边框拖动.全屏.缩放 版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/lwwl12/article/details/78059361 先看效果 ...

  5. vue封装公用弹出框方法,实现点击出现操作弹出框

    vue封装公用弹出框方法,实现点击出现操作弹出框 如上图所示,这次要实现一个点击出现操作弹框的效果:并将这个功能封装成一个函数,便于在项目的多个地方使用. 具体思路是: 封装一个组件,组件保护一个插槽 ...

  6. 使用easeui dialog弹出框中使用CKeditor多次加载后无法编辑问题

    问题呈现:弹出框页面 <tr class="addtr"> <th>内容</th> <td> <!-- <textare ...

  7. 关于隐式创建vue实例实现简化弹出框组件显示步骤

    我们在使用vue写alert组件的时候,经常是定义了一个alert.vue,然后引入alert.vue,然后配置参数等等,非常繁琐,那有没有一种方式可以像window.alert("内容&q ...

  8. 弹出框插件——dialog

    基于jquery和dot.js弹出框插件,兼容IE6+等其他浏览器. 思想:弹出框元素插入body节点中,并在页面垂直居中显示(fixed定位),触发确定和关闭事件绑定. 注意ie6包含两个问题:一. ...

  9. Android--自定义弹出框-自定义dialog

    项目要用到弹出框,还要和苹果的样式一样(Android真是没地位),所以就自己定义了一个,不是很像(主要是没图),但是也还可以. 废话不多说了,直接上代码 1.先看布局文件 <?xml vers ...

  10. vue弹出框的封装

    依旧是百度不到自己想要的,就自己动手丰衣足食 弹出框做成单独的组件confirm.vue; <template> <transition name="mask-bg-fad ...

随机推荐

  1. GroundingDINO(一种开集目标检测算法)服务化,根据文本生成检测框

    背景 最近发现一个叫GroundingDINO的开集目标检测算法,所谓开集目标检测就是能检测的目标类别不局限于训练的类别,这个算法可以通过输入文本的prompt然后输出对应的目标框.可以用来做预标注或 ...

  2. 如何用ReadWriteLock实现一个通用的缓存中心?

    摘要:在并发场景中,Java SDK中提供了ReadWriteLock来满足读多写少的场景. 本文分享自华为云社区<[高并发]基于ReadWriteLock开了个一款高性能缓存>,作者:冰 ...

  3. R EnhancedVolcano 绘制火山图

    火山图是用于差异表达分析结果可视化的一种有效方法.今天,我们来介绍一个用于增强火山图绘制的强大 R 包:EnhancedVolcano ,该包拥有强大的绘图功能,用户可以简单的通过设置颜色.形状.大小 ...

  4. 19.详解AQS家族的成员:CountDownLatch

    关注王有志,一个分享硬核Java技术的互金摸鱼侠 欢迎你加入Java人的提桶跑路群:共同富裕的Java人 今天我们来聊一聊AQS家族中的另一个重要成员CountDownLatch.关于CountDow ...

  5. NSDI-2023 微软论文:解构有状态网络功能

    本文通过chatgpt代理站(支持gpt4):gptschools.cn翻译整理 微软Azure对每个虚拟机进行了为期三个月的网络监控,获得了新建.并发.PPS等指标情况,发现: 1) 网络功能负载不 ...

  6. 使用Docker将Vite Vue项目部署到Nginx二级目录

    Vue项目配置 使用Vite创建一个Vue项目,点我查看如何创建 配置打包路径 在Nginx中如果是二级目录,例如/web时,需要设置线上的打包路径 在项目跟路径下创建两个文件:.env.produc ...

  7. 有哪些ASIC加速技术可以实现低功耗运行?

    目录 文章主题: 10. 有哪些ASIC加速技术可以实现低功耗运行? 背景介绍:随着移动设备.物联网.云计算等应用场景的不断增长,功耗成为了一个日益重要的技术问题.为了在移动设备上实现更长时间的运行, ...

  8. GO 语言中 slice 的理解

    GO 语言中 slice 理解 为什么说 Go 语言的 slice 是引用类型,其底层实现明明是一个结构体? slice 的底层实现是一个包含三个字段的结构体:指向底层数组的指针.slice 的长度和 ...

  9. 关于SQL SERVER 字段类型char(n) , nchar(n) , varchar(n) , nvarchar(n)

    对于很多新手来说,经常被字段类型搞得晕头转向,今天我用通俗易懂的解释帮大家理解这些类型. 在数据库字段类型定义中,可以分为两大类,一类为Unicode类型,另一种就是非Unicode. Unicode ...

  10. 西门子S7系列PLC以太网通讯处理器编程调试方法

    捷米特(北京)科技有限公司研发的捷米特以太网通讯模块,转以太网通讯模块型号有ETH-S7200-JM01和ETH-S7300-JM01,适用于西门子S7-200/S7-300/S7-400.SMART ...