vxe-table 模态弹窗 modal 新增最小化功能、且最小化窗口可以进行层叠、且拖动窗口不允许拖出屏幕边界

背景:

      因为 vxe-table 模态弹窗 modal 默认没有最小化功能,且拖动窗口的时候,允许拖出屏幕边界的话,那么原来的界面可能就打不开,只能刷新系统了。所以只能修改源码来实现此功能,现在把代码公开出来给需要使用的人。(需要特别感谢我的同事何工,因为此功能主要是我同事何工实现的)

代码环境:Vue3 

一、实现最终效果如图

最小化窗口

拖动窗口不允许拖出屏幕边界

最小化窗口可以进行层叠

 二、代码实现过程如下

1、找到 node_modules\vxe-table\es\v-x-e-table\src\conf.js 文件,

定位到:dblclickZoom: true,

在其后增加代码:        dblclickMinus: true, //新增最小化  2023-6-2

2、找到 node_modules\vxe-table\es\modal\src\modal.js 文件,

2.1 定位到:showZoom: Boolean,

在其后增加代码:        showMinus: Boolean,//新增最小化  2023-6-2

2.2 定位到:

dblclickZoom: { type: Boolean, default: function () { return GlobalConfig.modal.dblclickZoom; } },

在其后增加代码: dblclickMinus: { type: Boolean, default: function () { return GlobalConfig.modal.dblclickMinus; } },//新增最小化  2023-6-2

2.3 定位到:zoomLocat: null,

在其后增加代码: isMinus: false,//新增最小化  2023-6-2

2.4 定位到:var revert = function

将方法代码改为:
        var revert = function () {
            return nextTick().then(function () {
                var zoomLocat = reactData.zoomLocat;
                if (zoomLocat) {
                    var boxElem = getBox();
                    reactData.zoomLocat = null;
                    Object.assign(boxElem.style, {
                        top: "".concat(zoomLocat.top, "px"),
                        left: "".concat(zoomLocat.left, "px"),
                        width: "".concat(zoomLocat.width, "px"),
                        height: "".concat(zoomLocat.height, "px")
                    });
                    reactData.isMinus = false;//新增最小化  2023-6-2
                    savePosStorage();
                }
            });
        };

 2.5.定位到:var toggleZoomEvent = function (evnt)

  在该方法后添加新toggleMinusEvent方法,代码代码如下: 
  //新增最小化  2023-6-2
        var toggleMinusEvent= function (evnt) {
            return nextTick().then(function () {
                var zoomLocat = reactData.zoomLocat;
                var boxElem = getBox();
                if (!zoomLocat) {
                    reactData.zoomLocat = {
                        top: boxElem.offsetTop,
                        left: boxElem.offsetLeft,
                        width: boxElem.offsetWidth + (boxElem.style.width ? 0 : 1),
                        height: boxElem.offsetHeight + (boxElem.style.height ? 0 : 1)
                    };
                }
                var left = 0;
                var bottom = 0;
                var isFind = true;
                while (isFind){
                     left += 5;
                     bottom += 10;
                    var _a = allActivedModals[0].props.isMinus;
                    var _b = allActivedModals[0].reactData.visible;
                    var lastModal_1 = XEUtils.max(allActivedModals, function (item) { return item.reactData.modalZindex; });
                    var _props=JSON.parse(JSON.stringify(allActivedModals[0].props));
                    const el = allActivedModals.find(
                        (_vm) =>  _vm.reactData.visible == true 
                                && _vm.reactData.isMinus == true 
                                &&  parseInt(_vm.getBox().style.bottom) == bottom 
                                &&  parseInt(_vm.getBox().style.left) == left 
                                &&  _vm.getBox().style.top == 'auto'                       
                    );
                    if(el)
                    {
                        left = left + 5;
                        bottom = bottom + parseInt(el.getBox().style.height) -30;
                        isFind = true;
                    }else {
                        isFind = false;
                    }     
                }            
                Object.assign(boxElem.style, {
                top: "auto",
                bottom:  "".concat(bottom, "px"),
                left: "".concat(left, "px"),
                width: "250px",
                height: "43px",
                overflow: "hidden"
                });
                reactData.isMinus = true;
                savePosStorage();        
            });
        };

2.6  定位到:var mousedownEvent = function (evnt)方法,

  将该方法修改代码如下: 
          var mousedownEvent = function (evnt) {
            var remember = props.remember, storage = props.storage;
            var zoomLocat = reactData.zoomLocat;
            var isMinus = reactData.isMinus;
            var marginSize = XEUtils.toNumber(props.marginSize);
            var boxElem = getBox();
            if ((!zoomLocat || isMinus) && evnt.button === 0 && !getEventTargetNode(evnt, boxElem, 'trigger--btn').flag) {
                evnt.preventDefault();
                var domMousemove_1 = document.onmousemove;
                var domMouseup_1 = document.onmouseup;
                var disX_1 = evnt.clientX - boxElem.offsetLeft;
                var disY_1 = evnt.clientY - boxElem.offsetTop;
                var _a = getDomNode(), visibleHeight_1 = _a.visibleHeight, visibleWidth_1 = _a.visibleWidth;
                document.onmousemove = function (evnt) {
                    evnt.preventDefault();
                    var offsetWidth = boxElem.offsetWidth;
                    var offsetHeight = boxElem.offsetHeight;
                    var minX = marginSize;
                    var maxX = visibleWidth_1 - offsetWidth - marginSize - 1;
                    maxX = Math.min( visibleWidth_1  - 42,maxX); //往最右边拖动。不能超过边界  2023-5-8
                    var minY = marginSize;
                    var maxY = visibleHeight_1 - offsetHeight - marginSize - 1;
                    maxY = Math.min((visibleHeight_1 - 42),maxY);//往下拖动。不能超过边界  2023-5-8
                    var left = evnt.clientX - disX_1;
                    var top = evnt.clientY - disY_1;
                    if (left > maxX) {
                        left = maxX;
                    }
                    if (left < minX) {
                        left = minX;
                    }
                    if (top > maxY) {
                        top = maxY;
                    }
                    if (top < minY) {
                        top = minY;
                    }
                    //自定义:拖动不能超过边界代码判断  --- 开始  hym 2023-5-8 --- 
                    if (top < 0)
                    {
                        top = 0;//上面不能超出边界
                    }
                    if (left < 0)
                    {
                        left = 0;//最左边不能超出边界
                    }
                   //自定义:拖动不能超过边界代码判断  --- 结束   --- 
                    boxElem.style.left = "".concat(left, "px");
                    boxElem.style.top = "".concat(top, "px");
                    boxElem.className = boxElem.className.replace(/\s?is--drag/, '') + ' is--drag';
                };
                document.onmouseup = function () {
                    document.onmousemove = domMousemove_1;
                    document.onmouseup = domMouseup_1;
                    if (remember && storage) {
                        nextTick(function () {
                            savePosStorage();
                        });
                    }
                    setTimeout(function () {
                        boxElem.className = boxElem.className.replace(/\s?is--drag/, '');
                    }, 50);
                };
            }
        };

2.7.定位到:var renderTitles = function ()方法,

  将该方法修改代码如下: 
          var renderTitles = function () {
            var _a = props.slots, propSlots = _a === void 0 ? {} : _a, showClose = props.showClose, showZoom = props.showZoom,showMinus = props.showMinus, title = props.title;//新增最小化  2023-6-2
            var zoomLocat = reactData.zoomLocat;
            var titleSlot = slots.title || propSlots.title;
            var cornerSlot = slots.corner || propSlots.corner;
            var titVNs = [
                h('div', {
                    class: 'vxe-modal--header-title'
                }, titleSlot ? getSlotVNs(titleSlot({ $modal: $xemodal })) : (title ? getFuncText(title) : GlobalConfig.i18n('vxe.alert.title')))
            ];
            var rightVNs = [];
            if (cornerSlot) {
                rightVNs.push(h('span', {
                    class: 'vxe-modal--corner-warpper'
                }, getSlotVNs(cornerSlot({ $modal: $xemodal }))));
            }
            //新增最小化  2023-6-2
            if (showMinus && !zoomLocat) {
                rightVNs.push(h('i', {
                    class: ['vxe-modal--minus-btn', 'trigger--btn', 'vxe-icon--minus'],
                    title: '最小化',
                    onClick: toggleMinusEvent
                }));
            }
            if (showZoom) {
                rightVNs.push(h('i', {
                    class: ['vxe-modal--zoom-btn', 'trigger--btn', zoomLocat ? GlobalConfig.icon.MODAL_ZOOM_OUT : GlobalConfig.icon.MODAL_ZOOM_IN],
                    title: GlobalConfig.i18n("vxe.modal.zoom".concat(zoomLocat ? 'Out' : 'In')),
                    onClick: toggleZoomEvent
                }));
            }
            if (showClose) {
                rightVNs.push(h('i', {
                    class: ['vxe-modal--close-btn', 'trigger--btn', GlobalConfig.icon.MODAL_CLOSE],
                    title: GlobalConfig.i18n('vxe.modal.close'),
                    onClick: closeEvent
                }));
            }
            titVNs.push(h('div', {
                class: 'vxe-modal--header-right'
            }, rightVNs));
            return titVNs;
        };

2.8 定位到:var renderHeaders = function ()方法,

  将该方法修改代码如下: 
        var renderHeaders = function () {
            var _a = props.slots, propSlots = _a === void 0 ? {} : _a, showZoom = props.showZoom, showMinus = props.showMinus, draggable = props.draggable;//新增最小化  2023-6-2
            var isMsg = computeIsMsg.value;
            var headerSlot = slots.header || propSlots.header;
            var headVNs = [];
            if (props.showHeader) {
                var headerOns = {};
                if (draggable) {
                    headerOns.onMousedown = mousedownEvent;
                }
                if (showZoom && props.dblclickZoom && props.type === 'modal') {
                    headerOns.onDblclick = toggleZoomEvent;
                }
                //新增最小化  2023-6-2
                if (showMinus && props.dblclickMinus && props.type === 'modal') {
                    headerOns.onDblclick = toggleMinusEvent;
                }
                headVNs.push(h('div', __assign({ class: ['vxe-modal--header', {
                            'is--draggable': draggable,
                            'is--ellipsis': !isMsg && props.showTitleOverflow
                        }] }, headerOns), headerSlot ? (!reactData.inited || (props.destroyOnClose && !reactData.visible) ? [] : getSlotVNs(headerSlot({ $modal: $xemodal }))) : renderTitles()));
            }
            return headVNs;
        };

三、使用方法

弹窗最小化使用方法  :添加属性    :show-minus="true"

例如

<template>
  <vxe-modal
    v-model="state.showDialog"
    width="600"
    height="170"
    min-width="600"
    min-height="150"
    :remember="true"
    :transfer="false"
    :lockView="false"
    :destroy-on-close="true"
    :esc-closable="true"
    show-zoom
    :show-minus="true"
    resize
    :loading="state.loading"
    :top="200"
    :margin-size="-500"
    show-footer
    :mask="false"
  >
    <template #footer>
      <el-button type="primary" @click="updateVisible(false)" size="default">关 闭</el-button>
    </template>
    <template #title>
      <span style="color: red">录音播放   </span>
    </template>
    <template #default>
      <div id="ScRx_Lybf">
        <div style="margin-left: 1px; margin-right: 1px; margin-top: 1px; float: left; width: 100%">
          <audio ref="scly_audio" style="width: 100%; outline: none" :src="Lyurl" controls="controls" autoplay="autoplay" @contextmenu.prevent />
        </div>
      </div>
    </template>
  </vxe-modal>
</template>

四、修改代码后怎样生效

详见我的另一篇文章:使用npm或yarn 下载依赖,修改依赖的源码后,怎样重新更新或下载依赖后,修改的源码能够生效

猜你喜欢

转载自blog.csdn.net/hymlx526/article/details/131055510