基于element-ui el-dialog组件封装,可缩放+可移动的弹窗组件

源码下载

改组件继承el-dialog组件百分之95属性,可直接对进行替换。在项目中我的命名为:

SkDialog。废话不多说,直接上代码:

vue代码:搞成组件,路径随意,推荐统一放在组件目录下








拖动及缩放操作js代码:

/**
 @author: kzy;
 */
import Vue from 'vue'
Vue.directive("SkDialogDrag", {
  bind(el, binding, vnode, oldVnode) {
    const windowW = document.body.clientWidth;
    const windowH = document.body.clientHeight
    //设置弹框可拉伸最小宽高
    let minWidth = 400;
    let minHeight = 300;
    const dialogHeaderEl = el.querySelector(".el-dialog__header");
    //弹窗
    const dragDom = el.querySelector(".el-dialog");
    //头部加上可拖动cursor
    dialogHeaderEl.style.cursor = "move";

    // 获取style属性
    const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);

    let moveDown = e => {
      // 鼠标按下,计算当前元素距离可视区的距离
      const disX = e.clientX - dialogHeaderEl.offsetLeft;
      const disY = e.clientY - dialogHeaderEl.offsetTop;

      // 获取到的值带px 正则匹配替换
      let styL, styT, styMT;
      // 注意在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, "");
        styMT = +sty.marginTop.replace(/\px/g, "")
      }

      document.onmousemove = function (e) {
        const titleH = dialogHeaderEl.offsetHeight;

        // 通过事件委托,计算移动的距离
        let l = e.clientX - disX;
        let t = e.clientY - disY;

        // 移动边界处理
        if (t < 0 && (t + styMT + styT) <= 0 || t < 0 && (styMT + styT) <= 0) {
          t = -(styMT + styT);
        } else if (t > 0 && t > (document.body.clientHeight - styMT - styT - titleH)) {
          t = document.body.clientHeight - styMT - styT - titleH;
        }

        // 移动当前元素
        dragDom.style.left = `${l + styL}px`;
        dragDom.style.top = `${t + styT}px`;

      };

      document.onmouseup = function (e) {
        document.onmousemove = null;
        document.onmouseup = null;
      };

    };

    dialogHeaderEl.onmousedown = moveDown;

    dragDom.onmousemove = function (e) {
      const dialogBODY = el.querySelector(".el-dialog__body");
      const resizeDom= el.querySelector(".resize");
      const titleH = dialogHeaderEl.offsetHeight;
      dragDom.onmousedown = e => {
        const clientX = e.clientX;
        const clientY = e.clientY;
        let elW = dragDom.clientWidth;
        let elH = dragDom.clientHeight;
        let EloffsetLeft = dragDom.offsetLeft;
        let EloffsetTop = dragDom.offsetTop;
        let ELscrollTop = el.scrollTop;
        let resizeW = resizeDom.clientWidth, resizeH = resizeDom.clientHeight;

        //判断点击的位置是不是为头部
        if (
          clientX > EloffsetLeft &&
          clientX < EloffsetLeft + elW &&
          clientY > EloffsetTop &&
          clientY < EloffsetTop + 100
        ) {
          //如果是头部
          e.preventDefault(); // 移动时禁用默认事件
        } else {
          document.onmousemove = function (e) {
            //鼠标拖拽
            if (
              clientX > EloffsetLeft + elW - resizeW  &&
              clientX < EloffsetLeft + elW
            ) {
              //往左拖拽
              if (clientX > e.clientX) {
                if (dragDom.clientWidth < minWidth) {
                } else {
                  dragDom.style.width = elW - (clientX - e.clientX) * 2 + "px";
                }
              }
              //往右拖拽
              if (clientX <= e.clientX) {
                let targetTW = elW + (e.clientX - clientX) * 2
                targetTW > windowW ?
                  dragDom.style.width = windowW + "px" :
                  dragDom.style.width = targetTW + "px"
              }
            }
            //底部鼠标拖拽位置
            if (
              ELscrollTop + clientY > EloffsetTop + elH - resizeH &&
              ELscrollTop + clientY < EloffsetTop + elH
            ) {
              //往上拖拽
              if (clientY > e.clientY) {
                if (dragDom.clientHeight < minHeight) {
                } else {
                  dragDom.style.height = elH - (clientY - e.clientY) * 1 + "px";
                  dialogBODY.style.height = elH - (clientY - e.clientY) * 1 - titleH + "px";
                }
              }
              //往下拖拽
              if (clientY <= e.clientY) {
                e.clientY >= windowH ?
                  dragDom.style.height = windowH - dragDom.offsetTop + "px" :
                  dragDom.style.height = elH + (e.clientY - clientY) * 1 + "px";
                dialogBODY.style.height = elH - (clientY - e.clientY) * 1 - titleH + "px";
              }
            }
          };
          //结束
          document.onmouseup = function (e) {
            document.onmousemove = null;
            document.onmouseup = null;
          };
        }
      };
    };
  }
});
export default Vue.directive('SkDialogDrag')

将skdialog.js注册为指令:

目录:

基于element-ui el-dialog组件封装,可缩放+可移动的弹窗组件_第1张图片

import SkDialogDrag from './dialog/skdialog'
const install = function(Vue) {
  Vue.directive('SkDialogDrag', SkDialogDrag)
}

指令使用:(v-指令名称(SkDialogDrag))

基于element-ui el-dialog组件封装,可缩放+可移动的弹窗组件_第2张图片

效果图:

基于element-ui el-dialog组件封装,可缩放+可移动的弹窗组件_第3张图片

注:吃水不忘挖井人,在 原作者wjqocean 的基础之上改进

你可能感兴趣的:(element,ui,vue.js,前端)