vue实现可拖拽的dialog弹框


Posted in Vue.js onMay 13, 2021

本文主要介绍了vue实现可拖拽的dialog弹框,分享给大家,具体如下:

vue实现可拖拽的dialog弹框

element的dialog弹框在项目中挺常用的。但有时候嵌套的话会遮住,体验不好。拖拽形式的弹框会提高用户体验

借助基于 Sortable.js 的 Vue 拖拽组件vuedraggable

安装

npm install vuedraggable --save

在公共组件中新建个js文件,搭配vue自定义指令来实现拖拽的效果

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;
            };
        }
    }
})

页面中使用 v-dialogDrag 即可实现想要的效果

<el-dialog
    v-dialogDrag
    :title="dialogTitle"
    :visible.sync="addDialogVisible"
    :before-close="handleClose"
    :close-on-click-modal="false"
    width="50%">
    <div class="add_columns">
        <div class="pull-organize">
            <div class="bm-title">部门管理</div>
            <el-tree
                :data="treeData"
                lazy:load="loadNode"
                accordion 
                :props="defaultProps"
                :default-expand-all="false">
            </el-tree>
        </div>
        <div class="show-information">
            <el-form inline>
                <el-form-item label="用户ID">
                    <el-input v-model="searchParams.userId" size="mini" ></el-input>
                </el-form-item>
                <el-form-item label="用户名">
                    <el-input v-model="searchParams.userName" size="mini"></el-input>
                </el-form-item>
                <el-form-item class="btn-item">
                    <el-button type="primary" @click="handleQuery" size="mini">查询</el-button>
                </el-form-item>
                    <el-form-item class="btn-item">
                    <el-button type="success" @click="hadnleAddPerson" size="mini">添加人员</el-button>
                </el-form-item>
            </el-form>
            <el-table
                :data="tableData"
                class="oneTabel"
                style="width:100%;">
                <el-table-column type="selection" width="50"></el-table-column>
                <el-table-column prop="id" width="60" label="登录ID"></el-table-column>
                <el-table-column prop="userName" label="用户名"></el-table-column>
                <el-table-column prop="education" label="部门"></el-table-column>
                <el-table-column prop="sex" label="手机"></el-table-column>
            </el-table>
        </div>
    </div>
</el-dialog>

到此这篇关于vue实现可拖拽的dialog弹框的文章就介绍到这了,更多相关vue 可拖拽弹框内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
vue3.0中setup使用(两种用法)
Dec 02 Vue.js
Vue与React的区别和优势对比
Dec 18 Vue.js
如何在vue中使用kindeditor富文本编辑器
Dec 19 Vue.js
vue 页面跳转的实现方式
Jan 12 Vue.js
Vue中的nextTick作用和几个简单的使用场景
Jan 25 Vue.js
vue 组件基础知识总结
Jan 26 Vue.js
vue实现轮播图帧率播放
Jan 26 Vue.js
Vue ​v-model相关知识总结
Jan 28 Vue.js
Vue中foreach数组与js中遍历数组的写法说明
Jun 05 Vue.js
vue Element-ui表格实现树形结构表格
Jun 07 Vue.js
vue postcss-px2rem 自适应布局
May 15 Vue.js
vue3不同环境下实现配置代理
May 25 Vue.js
vue如何批量引入组件、注册和使用详解
vue组件的路由高亮问题解决方法
Vue通过懒加载提升页面响应速度
Vue详细的入门笔记
如何理解Vue前后端数据交互与显示
Vue实现下拉加载更多
May 09 #Vue.js
如何使用vue3打造一个物料库
You might like
php smarty模版引擎中变量操作符及使用方法
2009/12/11 PHP
php初始化对象和析构函数的简单实例
2014/03/11 PHP
PHP代码判断设备是手机还是平板电脑(两种方法)
2015/10/19 PHP
PHP操作mysql数据库分表的方法
2016/06/09 PHP
PHP生成随机数的方法总结
2018/03/01 PHP
json数据处理技巧(字段带空格、增加字段、排序等等)
2013/06/14 Javascript
JavaScript中的setMilliseconds()方法使用详解
2015/06/11 Javascript
javascript父子页面通讯实例详解
2015/07/17 Javascript
jQuery实现只允许输入数字和小数点的方法
2016/03/02 Javascript
JQuery Mobile实现导航栏和页脚
2016/03/09 Javascript
轻松掌握JavaScript享元模式
2016/08/27 Javascript
nodejs连接mysql数据库简单封装示例-mysql模块
2017/04/10 NodeJs
将angular-ui的分页组件封装成指令的方法详解
2017/05/10 Javascript
使用JavaScript中的lodash编写双色球效果
2018/06/24 Javascript
vue实现通讯录功能
2018/07/14 Javascript
详解关于Angular4 ng-zorro使用过程中遇到的问题
2018/12/05 Javascript
Element Input输入框的使用方法
2020/07/26 Javascript
[06:43]2018DOTA2国际邀请赛寻真——VGJ.Thunder
2018/08/11 DOTA
python实现class对象转换成json/字典的方法
2016/03/11 Python
Python编程实现的图片识别功能示例
2017/08/03 Python
python爬取酷狗音乐排行榜
2019/02/20 Python
CSS3实现瀑布流布局与无限加载图片相册的实例代码
2016/12/22 HTML / CSS
瑞典手机壳品牌:Richmond & Finch
2018/04/28 全球购物
语文教育专业推荐信范文
2013/11/25 职场文书
办理退休介绍信
2014/01/09 职场文书
工程管理专业毕业生自荐信
2014/01/24 职场文书
优秀毕业生推荐信范文
2014/03/07 职场文书
小学评语大全
2014/04/22 职场文书
校庆团日活动总结
2014/08/28 职场文书
运动会跳远广播稿5篇
2014/09/17 职场文书
2015年电工工作总结
2015/04/10 职场文书
庆七一晚会主持词
2015/06/30 职场文书
导游词之南昌滕王阁
2019/11/29 职场文书
元素水平垂直居中的方式
2021/03/31 HTML / CSS
教你怎么用python实现字符串转日期
2021/05/24 Python
python blinker 信号库
2022/05/04 Python