返回

弹框自如移!vue el-dialog弹出框自定义指令轻松拖拽位置、宽度、高度

前端

自定义el-dialog拖拽指令,释放你的表单体验!

在实际开发中,我们常常需要使用el-dialog弹出框来创建表单。一般情况下,这些弹出框都是居中的,但这可能挡住下方的重要数据,造成不便。

为了解决这个问题,我们可以使用动态样式和鼠标事件来实现弹出框的拖拽。不过,自己写的代码可能在适配性和全面性上存在不足。

为了解决这个痛点,我们可以创建一个全局自定义指令,实现拖拽功能,并广泛应用于多个场景中。

创建拖拽指令

1. 创建directive文件夹和dialog文件夹

在src/文件夹下创建directive文件夹,并在其下创建dialog文件夹,用于存放与dialog相关的代码。

2. 创建dialog.js文件

在directive/dialog文件夹下创建一个dialog.js文件,并输入以下代码:

import Vue from "vue";

const dialogDrag = {
  inserted(el, binding) {
    const dialogHeader = el.querySelector(".el-dialog__header");
    const dragDom = el.querySelector(".el-dialog");
    dialogHeader.style.cursor = "move";

    const sty = `
      position: absolute;
      left: 0px;
      top: 0px;
    `;
    dragDom.setAttribute("style", sty);

    // 获取原有属性 ie dom操作直接使用 el.style.xxx = xxx
    let styL = +dragDom.style.left.replace(/\px/g, "");
    let styT = +dragDom.style.top.replace(/\px/g, "");

    // 鼠标点击时
    dialogHeader.onmousedown = (e) => {
      // 鼠标相对于dialog距离
      const disX = e.clientX - dialogHeader.offsetLeft;
      const disY = e.clientY - dialogHeader.offsetTop;
      // 获取当前可视区宽高
      const screenWidth = document.body.clientWidth;
      const screenHeight = document.body.clientHeight;

      const dragDialog = (e) => {
        // 防止dialog移出屏幕
        styL = e.clientX - disX;
        styT = e.clientY - disY;
        if (-styL > dragDom.offsetWidth - screenWidth) {
          styL = -(dragDom.offsetWidth - screenWidth);
        }
        if (styL > 0) {
          styL = 0;
        }
        if (-styT > dragDom.offsetHeight - screenHeight) {
          styT = -(dragDom.offsetHeight - screenHeight);
        }
        if (styT > 0) {
          styT = 0;
        }

        // 设置新的位置
        dragDom.style.cssText = `
              left: ${styL}px;
              top: ${styT}px;
            `;
      };

      // 解除鼠标弹起事件
      document.onmousemove = dragDialog;
      // 鼠标松开时
      document.onmouseup = (e) => {
        document.onmousemove = null;
        document.onmouseup = null;
      };
    };
  },
};

Vue.directive("dialogDrag", dialogDrag);

注册全局指令

在main.js文件中,将指令注册为全局指令:

import Vue from "vue";
import dialogDrag from "./directive/dialog/dialog.js";

Vue.directive("dialogDrag", dialogDrag);

使用拖拽指令

在需要使用指令的组件中,在el-dialog上使用指令即可:

<el-dialog :title="title" :visible.sync="visible" @close="handleClose" :draggable="false" dialog-drag>
  <!-- content -->
</el-dialog>

完成这些步骤后,你就可以使用指令来拖拽el-dialog弹出框了。

优点

使用这个拖拽指令具有以下优点:

  • 轻松拖拽el-dialog弹出框,不受居中限制
  • 可以查看被弹出框遮挡的数据
  • 适配性强,可在不同场景下使用
  • 作为全局指令,可以在多个组件中复用

常见问题解答

1. 如何禁用拖拽功能?

在使用el-dialog组件时,将:draggable属性设置为true即可禁用拖拽功能。

2. 拖拽指令支持哪些浏览器的版本?

该指令支持主流浏览器的高版本,如Chrome、Firefox、Safari、Edge等。

3. 可以同时拖拽多个弹出框吗?

是的,可以同时拖拽多个弹出框,但需要针对每个弹出框使用不同的dialogDrag指令。

4. 拖拽指令是否兼容不同的el-dialog组件样式?

该指令兼容不同样式的el-dialog组件,包括自定义的样式。

5. 如何防止弹出框被拖拽到屏幕外?

在指令的代码中,我们对弹出框的位置进行了限制,防止其超出屏幕范围。