Vue【原创】整合el-dialog,可拖动可全屏最大化弹出框
项目中很多时候需要弹出框可以拖动并且可最大化,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,可拖动可全屏最大化弹出框的更多相关文章
- 基于Vue.js PC桌面端弹出框组件|vue自定义弹层组件|vue模态框
vue.js构建的轻量级PC网页端交互式弹层组件VLayer. 前段时间有分享过一个vue移动端弹窗组件,今天给大家分享一个最近开发的vue pc端弹出层组件. VLayer 一款集Alert.Dia ...
- elementUI vue 页面加载的时候页面出现了黑字 页面优化处理 按钮弹出框文字
elementUI 页面如果需要加载很多东西的时候, 自己定义的按钮或者弹出框dialog的文字就会显示在页面上, 一闪而过, 因此需要优化一下, elementUI 提供的loading有遮罩层, ...
- vue--vant组件库Dialog弹出框
安装vant UI框架: cnpm install vant –-save-dev 导入组件-在main.js里: import Vant from 'vant'; import'vant/lib/v ...
- WPF无边框拖动、全屏、缩放
原文:WPF无边框拖动.全屏.缩放 版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/lwwl12/article/details/78059361 先看效果 ...
- vue封装公用弹出框方法,实现点击出现操作弹出框
vue封装公用弹出框方法,实现点击出现操作弹出框 如上图所示,这次要实现一个点击出现操作弹框的效果:并将这个功能封装成一个函数,便于在项目的多个地方使用. 具体思路是: 封装一个组件,组件保护一个插槽 ...
- 使用easeui dialog弹出框中使用CKeditor多次加载后无法编辑问题
问题呈现:弹出框页面 <tr class="addtr"> <th>内容</th> <td> <!-- <textare ...
- 关于隐式创建vue实例实现简化弹出框组件显示步骤
我们在使用vue写alert组件的时候,经常是定义了一个alert.vue,然后引入alert.vue,然后配置参数等等,非常繁琐,那有没有一种方式可以像window.alert("内容&q ...
- 弹出框插件——dialog
基于jquery和dot.js弹出框插件,兼容IE6+等其他浏览器. 思想:弹出框元素插入body节点中,并在页面垂直居中显示(fixed定位),触发确定和关闭事件绑定. 注意ie6包含两个问题:一. ...
- Android--自定义弹出框-自定义dialog
项目要用到弹出框,还要和苹果的样式一样(Android真是没地位),所以就自己定义了一个,不是很像(主要是没图),但是也还可以. 废话不多说了,直接上代码 1.先看布局文件 <?xml vers ...
- vue弹出框的封装
依旧是百度不到自己想要的,就自己动手丰衣足食 弹出框做成单独的组件confirm.vue; <template> <transition name="mask-bg-fad ...
随机推荐
- APP中RN页面热更新流程-ReactNative源码分析
平时使用WebStorm或VSCode对RN工程中的文件修改后,在键盘上按一下快捷cmd+s进行文件保存,此时当前调试的RN页面就会自动进行刷新,这是RN开发相比于原生开发一个很大的优点:热更新. 那 ...
- Abaqus结构仿真软件的非线性问题与解决方案
无论是什么FEA 软件,想要获得非线性问题的一些解决方法始终没有那么简单.遇到问题是很常见的,那么下面就来看看Abaqus用户克服这一类问题的解决方法吧. 1. 简化模型 从简化模型开始,通过逐渐添 ...
- CreateProcess error=2, 系统找不到指定的文件。
遇到一个android 配置.gradle时提示CreateProcess error=2, 系统找不到指定的文件 于是百度有很多这类答案,如:干掉NDK 我按照这么做了,最后顽固的bug 并没有理睬 ...
- 【python基础】基本数据类型-字符串类型
1.初识字符串 字符串就是一系列字符.在python中,用引号括起来文本内容的都是字符串. 其语法格式为:'文本内容'或者"文本内容" 我们发现其中的引号可以是单引号,也可以是双引 ...
- Python相关镜像
Python相关镜像 (1) pip使用说明 对于Python开发用户来讲,我们会经常使用pip安装软件包.但国外的源下载速度实在太慢,浪费时间且经常出现下载后安装出错问题.所以把PIP安装源替换成国 ...
- Java方法的概念以及方法的四种语法
一.方法 方法的概念 将一个功能抽取出来,放在类中的大括号中,形成一个独立的功能,当需要使用该功能时,则调用它,这样可以增强代码的复用性(重复利用),并解决代码的冗余现象. 方法的语法: [访 ...
- \n被当成回车处理
Regex.Escape C# 字符串变量str 的值为"a\nb"如果直接输出显示的话,就成了:ab需要输出显示为:a\nb string str = "a\nb& ...
- 为teamcity的代码语法检查工具pyflakes增加支持python2和python3
TeamCity和pyflakes TeamCity是一款由JetBrains公司开发的持续集成和部署工具,它提供了丰富的功能来帮助团队协作进行软件开发.其中包括代码检查.自动化构建.测试运行.版本控 ...
- Redis数据结构:高频面试题及解析
概述 Redis 是速度非常快的非关系型(NoSQL)内存键值数据库,可以存储键和五种不同类型的值之间的映射. 键的类型只能为字符串,值支持五种数据类型:字符串.列表.集合.散列表.有序集合. Red ...
- CANoe学习笔记(四):UDS常用否定响应
UDS中定义的否定响应代码常用的: ServiceNotSupported/服务不支持($11 ) 当诊断仪发送的请求消息中服务标识符无法识别或不支持时,ECU应发送该响应码 SubFunctionN ...