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 相关文章推荐
解决vue elementUI 使用el-select 时 change事件的触发问题
Nov 17 Vue.js
在Vue中使用mockjs代码实例
Nov 25 Vue.js
vue实现轮播图帧率播放
Jan 26 Vue.js
vue 数据双向绑定的实现方法
Mar 04 Vue.js
Vue + iView实现Excel上传功能的完整代码
Jun 22 Vue.js
SSM VUE Axios详解
Oct 05 Vue.js
Vue的过滤器你真了解吗
Feb 24 Vue.js
vue使用echarts实现折线图
Mar 21 Vue.js
vue的项目如何打包上线
Apr 13 Vue.js
vue中data里面的数据相互使用方式
Jun 05 Vue.js
vue实现input输入模糊查询的三种方式
Aug 14 Vue.js
vue实现简易音乐播放器
Aug 14 Vue.js
vue如何批量引入组件、注册和使用详解
vue组件的路由高亮问题解决方法
Vue通过懒加载提升页面响应速度
Vue详细的入门笔记
如何理解Vue前后端数据交互与显示
Vue实现下拉加载更多
May 09 #Vue.js
如何使用vue3打造一个物料库
You might like
解决Laravel 使用insert插入数据,字段created_at为0000的问题
2019/10/11 PHP
phpstorm激活码2020附使用详细教程
2020/09/25 PHP
jQuery中:submit选择器用法实例
2015/01/03 Javascript
超全面的vue.js使用总结
2017/02/12 Javascript
微信小程序之选项卡的实现方法
2017/09/29 Javascript
微信小程序scroll-view组件实现滚动动画
2018/01/31 Javascript
vue-cli常用设置总结
2018/02/24 Javascript
AngularJS 多指令Scope问题的解决
2018/10/25 Javascript
JavaScript中的一些实用小技巧总结
2019/04/07 Javascript
深入浅析vue-cli@3.0 使用及配置说明
2019/05/08 Javascript
jQuery Datatables 动态列+跨列合并实现代码
2020/01/30 jQuery
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
Vue环境搭建+VSCode+Win10的详细教程
2020/08/19 Javascript
基于Cesium绘制抛物弧线
2020/11/18 Javascript
Vue实现图书管理案例
2021/01/20 Vue.js
Python open()文件处理使用介绍
2014/11/30 Python
Win7下搭建python开发环境图文教程(安装Python、pip、解释器)
2016/05/17 Python
python中实现迭代器(iterator)的方法示例
2017/01/19 Python
200 行python 代码实现 2048 游戏
2018/01/12 Python
python爬虫 正则表达式解析
2019/09/28 Python
Django中使用Celery的方法步骤
2020/12/07 Python
CSS3 实用技巧:实现黑白图像效果示例代码
2013/07/11 HTML / CSS
浅谈HTML5 defer和async的区别
2016/06/07 HTML / CSS
旅游管理本科生求职信
2013/10/14 职场文书
网络教育自我鉴定
2013/11/01 职场文书
营业员实习自我鉴定
2013/12/07 职场文书
全国税务系统先进集体事迹材料
2014/05/19 职场文书
室内趣味活动方案
2014/08/24 职场文书
党员干部四风问题整改措施思想汇报
2014/10/12 职场文书
会议欢迎词
2015/01/23 职场文书
广告业务员岗位职责
2015/02/13 职场文书
银行先进个人总结
2015/02/15 职场文书
2015年财务经理工作总结
2015/05/13 职场文书
SqlServer: 如何更改表的文件组?(进而改变存储位置)
2021/04/05 SQL Server
python执行js代码的方法
2021/05/13 Python
Java多线程并发FutureTask使用详解
2022/06/28 Java/Android