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使用element-ui实现表单验证
Dec 13 Vue.js
Vue仿百度搜索功能
Dec 28 Vue.js
vue 使用饿了么UI仿写teambition的筛选功能
Mar 01 Vue.js
Vue2.x-使用防抖以及节流的示例
Mar 02 Vue.js
Vue鼠标滚轮滚动切换路由效果的实现方法
Aug 04 Vue.js
简单聊聊Vue中的计算属性和属性侦听
Oct 05 Vue.js
vue中 this.$set的使用详解
Nov 17 Vue.js
vue项目支付功能代码详解
Feb 18 Vue.js
vue中div禁止点击事件的实现
Apr 02 Vue.js
vue整合百度地图显示指定地点信息
Apr 06 Vue.js
vue打包时去掉所有的console.log
Apr 10 Vue.js
vue2的 router在使用过程中遇到的一些问题
Apr 13 Vue.js
vue如何批量引入组件、注册和使用详解
vue组件的路由高亮问题解决方法
Vue通过懒加载提升页面响应速度
Vue详细的入门笔记
如何理解Vue前后端数据交互与显示
Vue实现下拉加载更多
May 09 #Vue.js
如何使用vue3打造一个物料库
You might like
PHP 关于访问控制的和运算符优先级介绍
2013/07/08 PHP
PHP获取网页所有连接的方法(附demo源码下载)
2016/03/30 PHP
php接口实现拖拽排序功能
2018/04/23 PHP
jquery 与NVelocity 产生冲突的解决方法
2011/06/13 Javascript
JavaScript入门之基本函数详解
2011/10/21 Javascript
Jquery图形报表插件 jqplot简介及参数详解
2012/10/10 Javascript
8个超实用的jQuery功能代码分享
2015/01/08 Javascript
JS+CSS实现Div弹出窗口同时背景变暗的方法
2015/03/04 Javascript
jquery对复选框(checkbox)的操作汇总
2016/01/13 Javascript
Vue路由跳转问题记录详解
2017/06/15 Javascript
JS监控关闭浏览器操作的实例详解
2017/09/12 Javascript
详解在vue-cli中引用jQuery、bootstrap以及使用sass、less编写css
2017/11/08 jQuery
Vue中this.$router.push参数获取方法
2018/02/27 Javascript
解决vue+webpack打包路径的问题
2018/03/06 Javascript
vue实现父子组件之间的通信以及兄弟组件的通信功能示例
2019/01/29 Javascript
详解如何实现Element树形控件Tree在懒加载模式下的动态更新
2019/04/25 Javascript
[01:20:06]TNC vs VG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python实现查询苹果手机维修进度
2015/03/16 Python
python实现从字典中删除元素的方法
2015/05/04 Python
python微信公众号开发简单流程
2018/03/23 Python
python修改list中所有元素类型的三种方法
2018/04/09 Python
PyQt5每天必学之日历控件QCalendarWidget
2018/04/19 Python
Python 判断文件或目录是否存在的实例代码
2018/07/19 Python
Django更新models数据库结构步骤
2020/04/01 Python
win10从零安装配置pytorch全过程图文详解
2020/05/08 Python
python使用多线程+socket实现端口扫描
2020/05/28 Python
Java爬虫技术框架之Heritrix框架详解
2020/07/22 Python
Python实现爬取网页中动态加载的数据
2020/08/17 Python
html2canvas生成的图片偏移不完整的解决方法
2020/05/19 HTML / CSS
Happy Socks英国官网:购买五颜六色的袜子
2020/11/03 全球购物
大学生毕业求职简历的自我评价
2013/10/24 职场文书
公休请假条
2014/04/11 职场文书
户外拓展训练感想
2015/08/07 职场文书
Mysql 如何查询时间段交集
2021/06/08 MySQL
MySQL数据库安装方法与图形化管理工具介绍
2022/05/30 MySQL
VMware虚拟机安装 Windows Server 2022的详细图文教程
2022/09/23 Servers