项目中很多时候需要弹出框可以拖动并且可最大化,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. springboot 分析源码欢迎页和图标-> thymeleaf模板引擎常用语法->扩展

    欢迎页: icon: 注意点:  thymeleaf模板引擎 1.使用thymeleaf模板引擎前要导入对应依赖包 2.阅读源码: 根据源码说明我们可以将html文件放置在templates目录下,然 ...

  2. Galaxy Project 是一个由 NIH、NSF、Johns Hopkins University 等机构支持的开源生物医学开源项目。Galaxy 作为其中的一个子项目,提供了以英文为主,......

    本文分享自微信公众号 - 生信科技爱好者(bioitee).如有侵权,请联系 support@oschina.cn 删除.本文参与"OSC源创计划",欢迎正在阅读的你也加入,一起分 ...

  3. R 语言柱状图示例笔记

    由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文章中链接. 一.基础柱状图 1. barplot 命令 基于barplot基础柱状图颜色.方向及分组的绘 ...

  4. Prompt 手册——gpt-best-practices

    本文链接:https://www.cnblogs.com/wanger-sjtu/p/17470388.html 本文是 OpenAI gpt-best-practices 对如何使用GPT的Prom ...

  5. 前端vue自定义table 表格 表格组件 Excel组件

    快速实现vue uni-app自定义table 表格 表格组件 Excel组件,扩充性好,可切换四宫格 九宫格 十二宫格; 下载完整代码请访问uni-app插件市场地址:https://ext.dcl ...

  6. SAP ABAP 动态结构实现发送企业微信应用消息

    企业微信官方接口: 应用支持推送文本.图片.视频.文件.图文等类型. 请求方式:POST(HTTPS)请求地址: https://qyapi.weixin.qq.com/cgi-bin/message ...

  7. https 原理分析进阶-模拟https通信过程

    大家好,我是蓝胖子,之前出过一篇https的原理分析 ,完整的介绍了https概念以及通信过程,今天我们就来比较完整的模拟实现https通信的过程,通过这篇文章,你能了解到https核心的概念以及原理 ...

  8. WAMP apache 无法运行 报错could not execult menu item

    wamp:could not execult menu item (internal error)[exception]counld not perform service action:服务器没有及 ...

  9. 使用SpringBoot+React搭建一个Excel报表平台

    摘要:本文由葡萄城技术团队于博客园原创并首发.转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 前言 Excel报表平台是一款功能强大.操作简单的系统平台,可 ...

  10. Centos 7安装dotnet 3.1

    # 注册 Microsoft 密钥和源 sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft- ...