vue el-dialog弹出框自定义指令实现拖拽改变位置-宽度-高度

前言

  • 在实际开发中我们经常使用el-dialog弹出框做表单,一般情况都是居中。遮挡到了一部分数据

  • 当我们想要查看弹出框下面的数据时,就只能先把弹出框关闭,查看完数据之后在打开弹框

  • 我们通过动态样式,和鼠标事件就可以实现。但自己写的在适配性和全面性上还是有所欠缺的

  • 这种我们可以直接复制使用,写成全局自定义指令。多的地方使用,并且只做加法

代码实现-没有自定义指令情况下

1.来到src/创建directive文件夹

2.在src/directive/创建dialog文件夹专门用来放关于dialog的代码

3.在src/directive/dialog创建drag.js文件-弹出框的拖拽-代码如下

javascript 复制代码
/**
 * v-dialogDrag 弹窗拖拽
 */
export default {
  bind(el, binding, vnode, oldVnode) {
    const value = binding.value
    if (value === false) return
    // 获取拖拽内容头部
    const dialogHeaderEl = el.querySelector('.el-dialog__header');
    const dragDom = el.querySelector('.el-dialog');
    dialogHeaderEl.style.cursor = 'move';
    // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);
    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);
    dragDom.style.position = 'absolute';
    dragDom.style.marginTop = 0;
    let width = dragDom.style.width;
    if (width.includes('%')) {
      width = +document.body.clientWidth * (+width.replace(/%/g, '') / 100);
    } else {
      width = +width.replace(/\px/g, '');
    }
    dragDom.style.left = `${(document.body.clientWidth - width) / 2}px`;
    // 鼠标按下事件
    dialogHeaderEl.onmousedown = (e) => {
      // 鼠标按下,计算当前元素距离可视区的距离 (鼠标点击位置距离可视窗口的距离)
      const disX = e.clientX - dialogHeaderEl.offsetLeft;
      const disY = e.clientY - dialogHeaderEl.offsetTop;
​
      // 获取到的值带px 正则匹配替换
      let styL, styT;
​
      // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
      if (sty.left.includes('%')) {
        styL = +document.body.clientWidth * (+sty.left.replace(/%/g, '') / 100);
        styT = +document.body.clientHeight * (+sty.top.replace(/%/g, '') / 100);
      } else {
        styL = +sty.left.replace(/\px/g, '');
        styT = +sty.top.replace(/\px/g, '');
      }
​
      // 鼠标拖拽事件
      document.onmousemove = function (e) {
        // 通过事件委托,计算移动的距离 (开始拖拽至结束拖拽的距离)
        const l = e.clientX - disX;
        const t = e.clientY - disY;
​
        let finallyL = l + styL
        let finallyT = t + styT
​
        // 移动当前元素
        dragDom.style.left = `${finallyL}px`;
        dragDom.style.top = `${finallyT}px`;
​
      };
​
      document.onmouseup = function (e) {
        document.onmousemove = null;
        document.onmouseup = null;
      };
    }
  }
}
复制代码
​

4.在src/directive/dialog创建dragWidth.js文件-弹出框的宽度改变-代码如下

javascript 复制代码
/**
 * 可拖动弹窗宽度(右侧边)
 */
​
export default {
  bind(el) {
    const dragDom = el.querySelector('.el-dialog');
    const lineEl = document.createElement('div');
    lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
    lineEl.addEventListener('mousedown',
      function (e) {
        // 鼠标按下,计算当前元素距离可视区的距离
        const disX = e.clientX - el.offsetLeft;
        // 当前宽度
        const curWidth = dragDom.offsetWidth;
        document.onmousemove = function (e) {
          e.preventDefault(); // 移动时禁用默认事件
          // 通过事件委托,计算移动的距离
          const l = e.clientX - disX;
          dragDom.style.width = `${curWidth + l}px`;
        };
        document.onmouseup = function (e) {
          document.onmousemove = null;
          document.onmouseup = null;
        };
      }, false);
    dragDom.appendChild(lineEl);
  }
}
复制代码
​

5.在src/directive/dialog创建dragHeight.js文件-弹出框的宽度和高度改变-代码如下

javascript 复制代码
/**
 *  可拖动弹窗高度(右下角)- 也可以改变高度和宽度
 */
​
export default {
  bind(el) {
    const dragDom = el.querySelector('.el-dialog');
    const lineEl = document.createElement('div');
    lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
    lineEl.addEventListener('mousedown',
      function(e) {
        // 鼠标按下,计算当前元素距离可视区的距离
        const disX = e.clientX - el.offsetLeft;
        const disY = e.clientY - el.offsetTop;
        // 当前宽度 高度
        const curWidth = dragDom.offsetWidth;
        const curHeight = dragDom.offsetHeight;
        document.onmousemove = function(e) {
          e.preventDefault(); // 移动时禁用默认事件
          // 通过事件委托,计算移动的距离
          const xl = e.clientX - disX;
          const yl = e.clientY - disY
          dragDom.style.width = `${curWidth + xl}px`;
          dragDom.style.height = `${curHeight + yl}px`;
        };
        document.onmouseup = function(e) {
          document.onmousemove = null;
          document.onmouseup = null;
        };
      }, false);
    dragDom.appendChild(lineEl);
  }
}
复制代码
​

6.在src/directive/创建index.js文件-对自定义指令统一注册-代码如下

javascript 复制代码
// dialog弹出框-可拖动
import dialogDrag from './dialog/drag'
// dialog弹出框-宽度可拖动
import dialogDragWidth from './dialog/dragWidth'
// dialog弹出框-高度可拖动(也可拖动宽度)
import dialogDragHeight from './dialog/dragHeight'
​
const install = function (Vue) {
  // dialog弹出框-可拖动-使用v-dialogDrag
  Vue.directive('dialogDrag', dialogDrag)
  // dialog弹出框-宽度可拖动-使用v-dialogDragWidth
  Vue.directive('dialogDragWidth', dialogDragWidth)
  // dialog弹出框-高度可拖动(也可拖动宽度)- 使用v-dialogDragHeight
  Vue.directive('dialogDragHeight', dialogDragHeight)
}
​
​
export default install
复制代码
​

7.来到main.js引入注册

javascript 复制代码
// 自定义指令
import directive from './directive'
​
// 挂载
Vue.use(directive)

8.来到页面使用


总结:

经过这一趟流程下来相信你也对 vue el-dialog弹出框自定义指令实现拖拽改变位置-宽度-高度 有了初步的深刻印象,但在实际开发中我 们遇到的情况肯定是不一样的,所以我们要理解它的原理,万变不离其宗。加油,打工人!

什么不足的地方请大家指出谢谢 -- 風过无痕

相关推荐
To_OC9 小时前
从一头雾水到跑通全流程:我用一个周末啃透了JWT登录鉴权
前端·后端·http
excel10 小时前
研究 Vue 3 源码的收获
前端·vue.js
可乐鸡翅yeah_12 小时前
业务中 M3U8 水印相关坑,硬水印和动态水印区别
前端·网络·数据库·ffmpeg·m3u8在线
lerhxx12 小时前
AI 应用如何高效优雅地恢复中断?—— "连接解耦 + 状态持久化"
前端·javascript
计算机魔术师12 小时前
METR 演示 AI 智能体如何篡改 Inspect 评估记录以掩盖不当行为
前端
前端snow13 小时前
ai agent --- 异步处理之 Rabbit MQ
前端
念何架构之路13 小时前
zap扩展生态与总结
java·前端·数据库
独孤九剑打醒他13 小时前
【原创开源】【概念设计】源 - 栅 - 漏 - 栅 - 源 横向双栅 MOS,低压交流多值逻辑芯片探索
前端·其他·架构·开源·硬件工程
mantou13214 小时前
我给 AI Agent 做了个「油猴」:让 Claude Code / Codex 直接用你已登录的浏览器
前端·javascript·后端
默_笙14 小时前
🍕 一个主编、三个工种、两本手册:搭一支 AI 调研队
前端·javascript