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.
Closed this issue · 1 comments
MonkeyLiang commented
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页面但弹框仍然显示
github-actions commented
Hello @MonkeyLiang, your issue has been closed because it does not conform to our issue requirements. Please use the Issue Helper to create an issue, thank you!
你好 @MonkeyLiang,为了能够进行高效沟通,我们对 issue 有一定的格式要求,你的 issue 因为不符合要求而被自动关闭。你可以通过 issue 助手 来创建 issue 以方便我们定位错误。谢谢配合!