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动态合并单元格并添加小计合计功能示例
Nov 26 Vue.js
vue3.0实现插件封装
Dec 14 Vue.js
Vue 简单实现前端权限控制的示例
Dec 25 Vue.js
vue实现登录功能
Dec 31 Vue.js
vue浏览器返回监听的具体步骤
Feb 03 Vue.js
vue3如何优雅的实现移动端登录注册模块
Mar 29 Vue.js
vue3使用vue-router的完整步骤记录
Jun 20 Vue.js
vue.js Router中嵌套路由的实用示例
Jun 27 Vue.js
vue使用echarts实现折线图
Mar 21 Vue.js
使用vue判断当前环境是安卓还是IOS
Apr 12 Vue.js
如何优化vue打包文件过大
Apr 13 Vue.js
vue项目如何打包之项目打包优化(让打包的js文件变小)
Apr 30 Vue.js
vue如何批量引入组件、注册和使用详解
vue组件的路由高亮问题解决方法
Vue通过懒加载提升页面响应速度
Vue详细的入门笔记
如何理解Vue前后端数据交互与显示
Vue实现下拉加载更多
May 09 #Vue.js
如何使用vue3打造一个物料库
You might like
php fckeditor 调用的函数
2009/06/21 PHP
php新建文件自动编号的思路与实现
2011/06/27 PHP
PHP对表单提交特殊字符的过滤和处理方法汇总
2014/02/18 PHP
PHP+MySQL实现无极限分类栏目的方法
2015/12/23 PHP
PHP有序表查找之二分查找(折半查找)算法示例
2018/02/09 PHP
PHP扩展Swoole实现实时异步任务队列示例
2019/04/13 PHP
PHP基于进程控制函数实现多线程
2020/12/09 PHP
jQuery get和post 方法传值注意事项
2009/11/03 Javascript
ExtJS 工具栏 分页事件参数
2010/03/05 Javascript
用jQuery中的ajax分页实现代码
2011/09/20 Javascript
js/jquery去掉空格,回车,换行示例代码
2013/11/05 Javascript
js函数模拟显示桌面.scf程序示例
2014/04/20 Javascript
js中函数调用的两种常用方法使用介绍
2014/07/17 Javascript
js实现刷新iframe的方法汇总
2015/04/27 Javascript
jQuery实现获取绑定自定义事件元素的方法
2015/12/02 Javascript
jQuery遍历DOM元素与节点方法详解
2016/04/14 Javascript
js省市区级联查询(插件版&amp;无插件版)
2017/03/21 Javascript
Vue 2.X的状态管理vuex记录详解
2017/03/23 Javascript
利用jquery去掉时光轴头尾部线条的方法实例
2017/06/16 jQuery
详解vue-cli中的ESlint配置文件eslintrc.js
2017/09/25 Javascript
详解设置Webstorm 利用babel将ES6自动转码成ES5
2017/12/20 Javascript
JS中的BOM应用
2018/02/02 Javascript
如何用原生js写一个弹窗消息提醒插件
2019/05/24 Javascript
js实现弹幕飞机效果
2020/08/27 Javascript
vue 中的动态传参和query传参操作
2020/11/09 Javascript
分析Python读取文件时的路径问题
2018/02/11 Python
python实现从文件中读取数据并绘制成 x y 轴图形的方法
2018/10/14 Python
python英语单词测试小程序代码实例
2019/09/09 Python
Python使用内置函数setattr设置对象的属性值
2020/10/16 Python
Python爬虫模拟登陆哔哩哔哩(bilibili)并突破点选验证码功能
2020/12/21 Python
纽约现代艺术博物馆商店:MoMA STORE(室内家具和杂货商品)
2016/08/02 全球购物
Delphi CS笔试题
2014/01/04 面试题
大学军训感言200字
2014/02/26 职场文书
销售工作决心书
2015/02/04 职场文书
2016春季田径运动会广播稿
2015/12/21 职场文书
Python使用scapy模块发包收包
2021/05/07 Python