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 +WebSocket + WaveSurferJS 实现H5聊天对话交互的实例
Nov 18 Vue.js
vue 获取到数据但却渲染不到页面上的解决方法
Nov 19 Vue.js
vue 使用rules对表单字段进行校验的步骤
Dec 25 Vue.js
Vue实现简易购物车页面
Dec 30 Vue.js
vue watch监控对象的简单方法示例
Jan 07 Vue.js
手动实现vue2.0的双向数据绑定原理详解
Feb 06 Vue.js
vue3.0 项目搭建和使用流程
Mar 04 Vue.js
一文带你理解vue创建一个后台管理系统流程(Vue+Element)
May 18 Vue.js
Vue h函数的使用详解
Feb 18 Vue.js
vue中this.$http.post()跨域和请求参数丢失的解决
Apr 08 Vue.js
vue 自定义的组件绑定点击事件
Apr 21 Vue.js
vue递归实现树形组件
Jul 15 Vue.js
vue如何批量引入组件、注册和使用详解
vue组件的路由高亮问题解决方法
Vue通过懒加载提升页面响应速度
Vue详细的入门笔记
如何理解Vue前后端数据交互与显示
Vue实现下拉加载更多
May 09 #Vue.js
如何使用vue3打造一个物料库
You might like
桌面中心(一)创建数据库
2006/10/09 PHP
linux下为php添加curl扩展的方法
2011/07/29 PHP
php站内搜索并高亮显示关键字的实现代码
2011/12/29 PHP
PHP实现的简单mock json脚本分享
2015/02/10 PHP
Linux系统下PHP-FPM的安装和配置教程
2015/08/17 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
2015/12/19 PHP
js jquery做的图片连续滚动代码
2008/01/06 Javascript
jQuery中get()方法用法实例
2014/12/27 Javascript
浅谈jquery事件处理
2015/04/24 Javascript
js实现页面跳转的几种方法小结
2016/05/16 Javascript
jQuery图片前后对比插件beforeAfter用法示例【附demo源码下载】
2016/09/20 Javascript
AngularJS实现用户登录状态判断的方法(Model添加拦截过滤器,路由增加限制)
2016/12/12 Javascript
用jQuery实现圆点图片轮播效果
2017/03/19 Javascript
Extjs 中的 Treepanel 实现菜单级联选中效果及实例代码
2017/08/22 Javascript
微信小程序中上传图片并进行压缩的实现代码
2018/08/28 Javascript
angular中两种表单的区别(响应式和模板驱动表单)
2018/12/06 Javascript
VUE搭建手机商城心得和遇到的坑
2019/02/21 Javascript
vue使用vuex实现首页导航切换不同路由的方法
2019/05/08 Javascript
Angular2实现的秒表及改良版示例
2019/05/10 Javascript
Vue环境搭建+VSCode+Win10的详细教程
2020/08/19 Javascript
如何通过Proxy实现JSBridge模块化封装
2020/10/22 Javascript
[02:17]2016国际邀请赛中国区预选赛VG战队领队采访
2016/06/26 DOTA
2款Python内存检测工具介绍和使用方法
2014/06/01 Python
在Django的form中使用CSS进行设计的方法
2015/07/18 Python
python实现多线程抓取知乎用户
2016/12/12 Python
Python实现Dijkstra算法
2018/10/17 Python
Python中的异常处理try/except/finally/raise用法分析
2019/02/28 Python
python中文分词库jieba使用方法详解
2020/02/11 Python
使用jupyter Nodebook查看函数或方法的参数以及使用情况
2020/04/14 Python
三步解决python PermissionError: [WinError 5]拒绝访问的情况
2020/04/22 Python
捷克汽车配件和工具销售网站:TorriaCars
2018/02/26 全球购物
Quiksilver荷兰官方网站:冲浪和滑雪板
2019/11/16 全球购物
学生会个人自荐书范文
2014/02/12 职场文书
教师党员一句话承诺
2014/03/28 职场文书
公共场所禁烟标语
2014/06/25 职场文书
Golang 并发编程 SingleFlight模式
2022/04/26 Golang