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 18 Vue.js
vue祖孙组件之间的数据传递案例
Dec 07 Vue.js
如何在vue 中使用柱状图 并自修改配置
Jan 21 Vue.js
WebStorm无法正确识别Vue3组合式API的解决方案
Feb 18 Vue.js
vue打开新窗口并实现传参的图文实例
Mar 04 Vue.js
vue组件的路由高亮问题解决方法
May 11 Vue.js
Vue3.0写自定义指令的简单步骤记录
Jun 27 Vue.js
vue3获取当前路由地址
Feb 18 Vue.js
详解Vue中$props、$attrs和$listeners的使用方法
Feb 18 Vue.js
vue 自定义的组件绑定点击事件
Apr 21 Vue.js
vue router 动态路由清除方式
May 25 Vue.js
Vue 打包后相对路径的引用问题
Jun 05 Vue.js
vue如何批量引入组件、注册和使用详解
vue组件的路由高亮问题解决方法
Vue通过懒加载提升页面响应速度
Vue详细的入门笔记
如何理解Vue前后端数据交互与显示
Vue实现下拉加载更多
May 09 #Vue.js
如何使用vue3打造一个物料库
You might like
解析htaccess伪静态的规则
2013/06/18 PHP
php获取数组长度的方法(有实例)
2013/10/27 PHP
PHP获取当前url的具体方法全面解析
2013/11/26 PHP
合并ThinkPHP配置文件以消除代码冗余的实现方法
2014/07/22 PHP
php向js函数传参的几种方法
2014/08/10 PHP
php封装的数据库函数与用法示例【参考thinkPHP】
2016/11/08 PHP
微信开发之php表单微信中自动提交两次问题解决办法
2017/01/08 PHP
laravel实现简单用户权限的示例代码
2019/05/28 PHP
解决iframe的frameborder在chrome/ff/ie下的差异
2010/08/12 Javascript
editable.js 基于jquery的表格的编辑插件
2011/10/24 Javascript
js中eval()函数和trim()去掉字符串左右空格应用
2013/02/02 Javascript
js实现用户注册协议倒计时的方法
2015/01/21 Javascript
深入理解JavaScript系列(47):对象创建模式(上篇)
2015/03/04 Javascript
JavaScript中的原型prototype完全解析
2016/05/10 Javascript
jquery获取所有选中的checkbox实现代码
2016/05/26 Javascript
微信小程序 视图容器组件的详解及实例代码
2017/01/19 Javascript
vue.js学习之vue-cli定制脚手架详解
2017/07/02 Javascript
收藏AngularJS中最重要的核心功能
2017/07/09 Javascript
基于vue.js中关于下拉框的值默认及绑定问题
2018/08/22 Javascript
vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作
2020/11/16 Javascript
简洁的十分钟Python入门教程
2015/04/03 Python
让Python代码更快运行的5种方法
2015/06/21 Python
Python的地形三维可视化Matplotlib和gdal使用实例
2017/12/09 Python
Python列表解析配合if else的方法
2018/06/23 Python
python 顺时针打印矩阵的超简洁代码
2018/11/14 Python
python实现图片中文字分割效果
2019/07/22 Python
Pytorch在dataloader类中设置shuffle的随机数种子方式
2020/01/14 Python
Python selenium爬取微信公众号文章代码详解
2020/08/12 Python
Python日志打印里logging.getLogger源码分析详解
2021/01/17 Python
ziaja齐叶雅官方海外旗舰店:来自波兰的天然护肤品牌
2017/01/02 全球购物
《吃水不忘挖井人》教学反思
2014/04/15 职场文书
小学数学课后反思
2014/04/23 职场文书
爱耳日活动总结
2014/04/30 职场文书
安全例会汇报材料
2014/08/23 职场文书
大学生学习计划书
2014/09/15 职场文书
Python面向对象之内置函数相关知识总结
2021/06/24 Python