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中echarts的用法及与elementui-select的协同绑定操作
Nov 17 Vue.js
vue3.0实现点击切换验证码(组件)及校验
Nov 18 Vue.js
Vue开发中常见的套路和技巧总结
Nov 24 Vue.js
vue3.0+vue-router+element-plus初实践
Dec 02 Vue.js
vue+element实现动态加载表单
Dec 13 Vue.js
Vue如何跨组件传递Slot的实现
Dec 14 Vue.js
vue 在服务器端直接修改请求的接口地址
Dec 19 Vue.js
vuex的使用步骤
Jan 06 Vue.js
Vue中避免滥用this去读取data中数据
Mar 02 Vue.js
HTML+VUE分页实现炫酷物联网大屏功能
May 27 Vue.js
Vue3.0 手写放大镜效果
Jul 25 Vue.js
Vue自定义铃声提示音组件的实现
Jan 22 Vue.js
vue如何批量引入组件、注册和使用详解
vue组件的路由高亮问题解决方法
Vue通过懒加载提升页面响应速度
Vue详细的入门笔记
如何理解Vue前后端数据交互与显示
Vue实现下拉加载更多
May 09 #Vue.js
如何使用vue3打造一个物料库
You might like
php 字符过滤类,用于过滤各类用户输入的数据
2009/05/27 PHP
PHP操作MongoDB时的整数问题及对策说明
2011/05/02 PHP
wordpress自定义url参数实现路由功能的代码示例
2013/11/28 PHP
PHP简单判断iPhone、iPad、Android及PC设备的方法
2016/10/11 PHP
js自带函数备忘 数组
2006/12/29 Javascript
jQuery 页面载入进度条实现代码
2009/02/08 Javascript
javascript写的一个链表实现代码
2009/10/25 Javascript
菜鸟javascript基础整理1
2010/12/06 Javascript
基于Jquery的仿照flash放大图片效果代码
2011/03/16 Javascript
IE与FireFox中的childNodes区别
2011/10/20 Javascript
js读写(删除)Cookie实例详解
2013/04/17 Javascript
JS数组(Array)处理函数整理
2014/12/07 Javascript
JQuery的attr 与 val区别
2016/06/12 Javascript
全面了解函数声明与函数表达式、变量提升
2016/08/09 Javascript
AngularJS extend用法详解及实例代码
2016/11/15 Javascript
jquery+ajax实现省市区三级联动效果简单示例
2017/01/04 Javascript
jQuery.ajax向后台传递数组问题的解决方法
2017/05/12 jQuery
javascript+html5+css3自定义提示窗口
2017/06/21 Javascript
js实现随机8位验证码
2020/07/24 Javascript
详解基于Vue/React项目的移动端适配方案
2019/08/23 Javascript
js对象简介与基本用法示例
2020/03/13 Javascript
Python3学习urllib的使用方法示例
2017/11/29 Python
python itchat给指定联系人发消息的方法
2019/06/11 Python
python定间隔取点(np.linspace)的实现
2019/11/27 Python
python 5个顶级异步框架推荐
2020/09/09 Python
Aosom西班牙:家具在线商店
2020/06/11 全球购物
请说出你所知道的线程同步的方法
2013/04/19 面试题
工程管理专业毕业生自荐信
2014/01/24 职场文书
ktv筹备计划书
2014/05/03 职场文书
诚信贷款承诺书
2014/05/30 职场文书
2014四风问题对照检查材料范文
2014/09/15 职场文书
股东授权委托书
2014/10/15 职场文书
大学生求职自荐信
2015/03/24 职场文书
火烧圆明园的观后感
2015/06/03 职场文书
python 爬取天气网卫星图片
2021/06/07 Python
使用@Value值注入及配置文件组件扫描
2021/07/09 Java/Android