Skip to content

After globally encapsulating a-modal, it runs properly locally, but after deployment and release, the modal does not close when navigating back using the browser's back button, whereas it automatically closes in the local environment. #8367

@MonkeyLiang

Description

@MonkeyLiang

Version
4.2.6

Environment
win11, edge版本 140.0.3485.81 (正式版本) (64 位)、 vue3.4.27、vite 5.2.1

Steps to reproduce
目录结构 components --dragable-modal.vue views -- pageA.vue -- pageB.vue

分隔
dragable-modal.vue

目录结构
components
--dragable-modal.vue
views
-- pageA.vue
-- pageB.vue

分隔

dragable-modal.vue

<template>   
<a-modal ref="modalRef" v-model:open="visible" :wrap-style="{ overflow: 'hidden' }" :mask-closable="false"            :mask="mask" :keyboard="false" :closable="closable" :class="isFull?'full-modal':'draggle-modal'"            :width="width" wrap-class-name="custom-modal" @cancel="cancel" :destroyOnClose="destroyOnClose"            :maskClosable="maskClosable">     
<template #title>       
<div ref="modalTitleRef" class="title">{{ title }}</div>       
<div class="full-screen" v-if="hasFull">         
<FullscreenOutlined v-show="!isFull" @click="isFull=true"/>         
<FullscreenExitOutlined v-show="isFull" @click="isFull=false"/>       
</div>     </template>      
<template #modalRender="{ originVNode }">
       <div class="modal-content" :style="transformStyle">
         <component :is="originVNode"/>
       </div>
     </template>
     <div v-if="type=='img'" class="content-box">
       <slot></slot>
     </div>
     <div v-else>
       <slot></slot>
     </div>
     <template #footer v-if="type!='img'">
       <slot name="footer"></slot>
     </template>
   </a-modal>
 </template>
  <script setup>
 import {computed, nextTick, onUnmounted, ref, watch, watchEffect} from "vue";
 import {useDraggable} from '@vueuse/core';
  const emit = defineEmits(['cancel']);
 const props = defineProps({
   title: { // 弹窗标题
     type: String,
     default: "预览",
   },
   open: { // 弹窗是否显示
     type: Boolean,
     default: false,
   },
   hasFull: { // 是否含有全屏功能
     type: Boolean,
     default: true
   },
   width: { // 弹窗宽度 
    type: Number,
     default: 600,
   },
   // height: { // 弹窗高度
   //   type: Number,
   //   default: 'auto',
   // },
   mask: { // 弹窗是否显示遮罩
     type: Boolean,
     default: true,
   },
   destroyOnClose: {
     type: Boolean,
     default: true
   },
   maskClosable: {
     type: Boolean,
     default: true
   },
   type: { // 弹窗类型,分普通和img
     type: String,
     default: 'info'
   },
   footer: {
     type: Object,
     default: undefined,
   },
   closable: {
     type: Boolean,
     default: true
   } });
   const visible = ref(false); // 弹窗是否显示
 const modalTitleRef = ref(null); // 标题
 const isFull = ref(false); // 是否全屏
   const {x, y, isDragging} = useDraggable(modalTitleRef);
  const startX = ref(0); // 开始位置
 x const startY = ref(0); // 开始位置
 y const startedDrag = ref(false); // 是否开始拖拽
 const bodyRect = document.body.getBoundingClientRect();
 const defaultX = props.type == 'img' ? ((bodyRect.width - props.width) / 2 - 150) : 0; const transformX = ref(defaultX); // 当前偏移位置
 x const transformY = ref(0); // 当前偏移位置
 y const preTransformX = ref(0); // 上一次偏移位置
 x const preTransformY = ref(0); // 上一次偏移位置 y
 // 初始化弹框
 const initModal = (val) => {
   visible.value = val;
 };
  watch(() => props.open, (val) => {
   initModal(val) }, {immediate: true}) 
 // 定义拖拽区域边界
 const dragRect = ref({
   left: 0, // 左边界
   right: 0,  // 右边界
   top: 0,  // 上边界
   bottom: 0, // 下边界
 });
  // 监听拖拽位置
 watch([x, y], () => {
   if (!isFull.value) {
     if (!startedDrag.value) {
       startX.value = x.value;
       startY.value = y.value;
       const bodyRect = document.body.getBoundingClientRect();
       const titleRect = modalTitleRef.value.getBoundingClientRect();
       dragRect.value.right = bodyRect.width - titleRect.width;
       dragRect.value.bottom = bodyRect.height - titleRect.height;
       preTransformX.value = transformX.value;
       preTransformY.value = transformY.value;
     }
     startedDrag.value = true;
   }
  }); 
// 监听拖拽状态
 watch(isDragging, () => {
   if (!isDragging) {
     startedDrag.value = false;
   } });
 // 监听拖拽偏移
 watchEffect(() => {
   if (startedDrag.value) {
     transformX.value =         preTransformX.value +         Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) -         startX.value;     transformY.value =         preTransformY.value +         Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) -         startY.value; 
  }
 });
 // 拖拽偏移样式
 const transformStyle = computed(() => {
   return {
     transform: `translate(${transformX.value}px, ${transformY.value}px)`,
   };
 });
  // 全屏切换
 watch(isFull, (val) => {
   if (val) {
     transformX.value = 0;
     transformY.value = 0;
     startedDrag.value = false;
   } else {
     nextTick(() => {
       if (preTransformX.value === 0 && preTransformY.value === 0) {
         transformX.value = defaultX;
       } else {
         transformX.value =  preTransformX.value +   Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) -    startX.value;                                     
         transformY.value =  preTransformY.value +   Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) -  startY.value;
       }
     });
    }
 })
  function cancel() {
   emit('cancel');
 }  
 </script>
 <style lang="less">
 .ant-modal-wrap {
   &.custom-modal {
     pointer-events: none;
      .ant-modal {
       padding-bottom: 0;
        .modal-content {
         width: 100%; 
        height: 100%; 
        pointer-events: auto; 
      }
        .ant-modal-content {
         width: 100%; 
        height: 100%; 
        padding: 0; 
        border-radius: 4px;
         overflow: hidden; 
         .ant-modal-header {
           margin-bottom: 0;
           cursor: move;
           border-bottom: 1px solid #f4f4f4;
            .title {
             padding: 5px 15px;
             overflow: hidden;
             text-overflow: ellipsis;
             white-space: nowrap;
             width: calc(100% - 60px);
           }
            .full-screen {
             position: absolute;
             top: 6px;
             right: 45px;
             padding: 0 5px;
           }
         }
          .ant-modal-close {
           top: 7px;
         }
          .ant-modal-body {
           height: calc(100% - 34px);
           padding: 0 10px;
            .content-box {
             height: 100%
           }
         }
       }
       &.full-modal {
         width: 100% !important;
         height: 100% !important;
         max-width: 100%;
         top: 0;
         left: 0;
         padding-bottom: 0;
         margin: 0;
          .modal-content {
           .ant-modal-content {
             .ant-modal-header {
               cursor: default;
             }
           }
         }
       }
        &.modal-form-box, &.smart-approve-modal {
         .ant-modal-content {
           padding: 5px 15px 15px;
             .ant-modal-title {
             .title {
               padding-left: 0;
             }
           }
            .ant-modal-body {
             padding: 10px 5px 0px;
             height: auto;
             max-height: 70vh; 
            overflow-y: auto;
           }
         }
       }
     }
    }
  }
  </style>

pageA.vue

<template>  
    <a-button @click="openPageB">openPageB</a-button>
</template>
<script setup >
   function openPageB() {
      router.push('/pageB')
  }
</script>

pageB.vue

<template>  
    <dragbale-modal  :open="open" >
      <p>我是弹框</p>
   </dragbale-modal>
</template>
<script setup >
const open = ref(false);
   onMounted(() => {
       open.value=true;
    })
</script>

a页面点击按钮跳转B页面后,会弹出弹框, 此时点击浏览器回退按钮页面回退至A页面但弹框仍然显示

What is expected?
点击浏览器回退按钮页面回退至A页面弹框关闭

What is actually happening?
点击浏览器回退按钮页面回退至A页面但弹框仍然显示

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions