Quellcode durchsuchen

'添加可拖拽弹框'

lin-xin vor 7 Jahren
Ursprung
Commit
02c8872b67

+ 13 - 3
src/components/common/Sidebar.vue

@@ -94,12 +94,22 @@
                     },
                     {
                         icon: 'el-icon-rank',
-                        index: 'drag',
-                        title: '拖拽列表'
+                        index: '6',
+                        title: '拖拽组件',
+                        subs: [
+                            {
+                                index: 'drag',
+                                title: '拖拽列表',
+                            },
+                            {
+                                index: 'dialog',
+                                title: '拖拽弹框',
+                            }
+                        ]
                     },
                     {
                         icon: 'el-icon-lx-warn',
-                        index: '6',
+                        index: '7',
                         title: '错误处理',
                         subs: [
                             {

+ 80 - 0
src/components/common/directives.js

@@ -0,0 +1,80 @@
+import Vue from 'vue';
+
+// v-dialogDrag: 弹窗拖拽属性
+Vue.directive('dialogDrag', {
+    bind(el, binding, vnode, oldVnode) {
+        const dialogHeaderEl = el.querySelector('.el-dialog__header');
+        const dragDom = el.querySelector('.el-dialog');
+
+        dialogHeaderEl.style.cssText += ';cursor:move;'
+        dragDom.style.cssText += ';top:0px;'
+
+        // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
+        const sty = (() => {
+            if (window.document.currentStyle) {
+                return (dom, attr) => dom.currentStyle[attr];
+            } else {
+                return (dom, attr) => getComputedStyle(dom, false)[attr];
+            }
+        })()
+
+        dialogHeaderEl.onmousedown = (e) => {
+            // 鼠标按下,计算当前元素距离可视区的距离
+            const disX = e.clientX - dialogHeaderEl.offsetLeft;
+            const disY = e.clientY - dialogHeaderEl.offsetTop;
+
+            const screenWidth = document.body.clientWidth; // body当前宽度
+            const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取) 
+
+            const dragDomWidth = dragDom.offsetWidth; // 对话框宽度
+            const dragDomheight = dragDom.offsetHeight; // 对话框高度
+
+            const minDragDomLeft = dragDom.offsetLeft;
+            const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth;
+
+            const minDragDomTop = dragDom.offsetTop;
+            const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight;
+
+
+            // 获取到的值带px 正则匹配替换
+            let styL = sty(dragDom, 'left');
+            let styT = sty(dragDom, 'top');
+
+            // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
+            if (styL.includes('%')) {
+                styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100);
+                styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100);
+            } else {
+                styL = +styL.replace(/\px/g, '');
+                styT = +styT.replace(/\px/g, '');
+            };
+
+            document.onmousemove = function (e) {
+                // 通过事件委托,计算移动的距离 
+                let left = e.clientX - disX;
+                let top = e.clientY - disY;
+
+                // 边界处理
+                if (-(left) > minDragDomLeft) {
+                    left = -(minDragDomLeft);
+                } else if (left > maxDragDomLeft) {
+                    left = maxDragDomLeft;
+                }
+
+                if (-(top) > minDragDomTop) {
+                    top = -(minDragDomTop);
+                } else if (top > maxDragDomTop) {
+                    top = maxDragDomTop;
+                }
+
+                // 移动当前元素  
+                dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`;
+            };
+
+            document.onmouseup = function (e) {
+                document.onmousemove = null;
+                document.onmouseup = null;
+            };
+        }
+    }
+})

+ 36 - 0
src/components/page/DragDialog.vue

@@ -0,0 +1,36 @@
+<template>
+    <section class="main">
+        <div class="crumbs">
+            <el-breadcrumb separator="/">
+                <el-breadcrumb-item><i class="el-icon-rank"></i> 拖拽组件</el-breadcrumb-item>
+                <el-breadcrumb-item>拖拽弹框</el-breadcrumb-item>
+            </el-breadcrumb>
+        </div>
+        <div class="container">
+            <p>通过指令 v-dialogDrag 使 Dialog 对话框具有可拖拽的功能。</p>
+            <br>
+            <el-button type="primary" @click="visible = true;">点我弹框</el-button>
+        </div>
+        <el-dialog v-dialogDrag title="拖拽弹框" center :visible.sync="visible" width="30%">
+            我是一个可以拖拽的对话框!
+            <span slot="footer" class="dialog-footer">
+                <el-button @click="visible = false">取 消</el-button>
+                <el-button type="primary" @click="visible = false">确 定</el-button>
+            </span>
+        </el-dialog>
+    </section>
+</template>
+
+<script>
+export default {
+    data(){
+        return {
+            visible: false
+        }
+    }
+}
+</script>
+
+<style>
+
+</style>

+ 2 - 1
src/components/page/DragList.vue

@@ -2,7 +2,8 @@
     <section class="main">
         <div class="crumbs">
             <el-breadcrumb separator="/">
-                <el-breadcrumb-item><i class="el-icon-rank"></i> 拖拽排序</el-breadcrumb-item>
+                <el-breadcrumb-item><i class="el-icon-rank"></i> 拖拽组件</el-breadcrumb-item>
+                <el-breadcrumb-item>拖拽排序</el-breadcrumb-item>
             </el-breadcrumb>
         </div>
         <div class="container">

+ 1 - 0
src/main.js

@@ -6,6 +6,7 @@ import ElementUI from 'element-ui';
 import 'element-ui/lib/theme-chalk/index.css';    // 默认主题
 // import '../static/css/theme-green/index.css';       // 浅绿色主题
 import '../static/css/icon.css';
+import './components/common/directives';
 import "babel-polyfill";
 
 Vue.use(ElementUI, { size: 'small' });

+ 6 - 0
src/router/index.js

@@ -69,6 +69,12 @@ export default new Router({
                     component: resolve => require(['../components/page/DragList.vue'], resolve),
                     meta: { title: '拖拽列表' }
                 },
+                {
+                    // 拖拽Dialog组件
+                    path: '/dialog',
+                    component: resolve => require(['../components/page/DragDialog.vue'], resolve),
+                    meta: { title: '拖拽弹框' }
+                },
                 {
                     // 权限页面
                     path: '/permission',