🐛 [Bug]: The dialog box is used in combination with the picture upload component, and the image preview has the problem of masking layer by layer coverage.
Version
3.10.0
Vue Version
3.2.47
Link to minimal reproduction
<template>
<div>
<tiny-button @click="boxVisibility = true"> 右侧弹窗 </tiny-button>
<tiny-dialog-box right-slide v-model:visible="boxVisibility" title="消息">
<template #title>
<div class="header">
<span class="title">标题区</span>
<tiny-icon-help-circle class="icon"></tiny-icon-help-circle>
</div>
</template>
<div>
<tiny-file-upload
class="upload-demo picture-demo"
:action="action"
list-type="picture-card"
:file-list="fileList"
@preview="previewPicture"
>
<tiny-icon-plus class="tiny-svg-size" />
</tiny-file-upload>
<tiny-dialog-box v-model:visible="dialogVisible1" width="50%">
<img style="width: 100%" :src="dialogImageUrl1" alt="Preview Image" />
</tiny-dialog-box>
</div>
<template #footer>
<tiny-button type="primary" @click="boxVisibility = false"> 确 定 </tiny-button>
<tiny-button plain @click="boxVisibility = false"> 取消 </tiny-button>
</template>
</tiny-dialog-box>
</div>
</template>
<script setup lang="jsx">
import { ref } from 'vue'
import { Button as TinyButton, DialogBox as TinyDialogBox,FileUpload as TinyFileUpload } from '@opentiny/vue'
import { iconHelpCircle,iconPlus } from '@opentiny/vue-icon'
const action = ref('http://localhost:3000/api/upload')
const dialogVisible1 = ref(false)
const dialogImageUrl1 = ref('')
const fileList = ref([
{
name: 'fruit',
url: `https://res.hc-cdn.com/tiny-vue-web-doc/3.10.5.20230903162611/static/images/fruit.jpg`
}
])
const TinyIconPlus = iconPlus()
function previewPicture(file) {
dialogImageUrl1.value = file.url
dialogVisible1.value = true
}
const boxVisibility = ref(false)
const TinyIconHelpCircle = iconHelpCircle()
</script>
<style scoped>
.header {
display: flex;
align-items: center;
}
.header .title {
font-size: 20px;
font-weight: 600;
line-height: 1.5;
margin-right: 8px;
}
.header .icon {
margin-top: 2px;
font-size: 16px;
}
</style>
Step to reproduce
<template>
<div>
<tiny-button @click="boxVisibility = true"> 右侧弹窗 </tiny-button>
<tiny-dialog-box right-slide v-model:visible="boxVisibility" title="消息">
<template #title>
<div class="header">
<span class="title">标题区</span>
<tiny-icon-help-circle class="icon"></tiny-icon-help-circle>
</div>
</template>
<div>
<tiny-file-upload
class="upload-demo picture-demo"
:action="action"
list-type="picture-card"
:file-list="fileList"
@preview="previewPicture"
>
<tiny-icon-plus class="tiny-svg-size" />
</tiny-file-upload>
<tiny-dialog-box v-model:visible="dialogVisible1" width="50%">
<img style="width: 100%" :src="dialogImageUrl1" alt="Preview Image" />
</tiny-dialog-box>
</div>
<template #footer>
<tiny-button type="primary" @click="boxVisibility = false"> 确 定 </tiny-button>
<tiny-button plain @click="boxVisibility = false"> 取消 </tiny-button>
</template>
</tiny-dialog-box>
</div>
</template>
<script setup lang="jsx">
import { ref } from 'vue'
import { Button as TinyButton, DialogBox as TinyDialogBox,FileUpload as TinyFileUpload } from '@opentiny/vue'
import { iconHelpCircle,iconPlus } from '@opentiny/vue-icon'
const action = ref('http://localhost:3000/api/upload')
const dialogVisible1 = ref(false)
const dialogImageUrl1 = ref('')
const fileList = ref([
{
name: 'fruit',
url: `https://res.hc-cdn.com/tiny-vue-web-doc/3.10.5.20230903162611/static/images/fruit.jpg`
}
])
const TinyIconPlus = iconPlus()
function previewPicture(file) {
dialogImageUrl1.value = file.url
dialogVisible1.value = true
}
const boxVisibility = ref(false)
const TinyIconHelpCircle = iconHelpCircle()
</script>
<style scoped>
.header {
display: flex;
align-items: center;
}
.header .title {
font-size: 20px;
font-weight: 600;
line-height: 1.5;
margin-right: 8px;
}
.header .icon {
margin-top: 2px;
font-size: 16px;
}
</style>
What is expected
No response
What is actually happening
No response
Any additional comments (optional)
No response
Bot detected the issue body's language is not English, translate it automatically.
Title: 🐛 [Bug]: When the dialog box is used in combination with the image upload component, the image preview has a mask layer coverage problem.
图片炸了,可以补一下图片吗? @thestar077
Bot detected the issue body's language is not English, translate it automatically.
The picture is blown up. Can you please update the picture? @thestar077
将嵌套的dialog-box的append-to-body属性设置为true @thestar077
https://opentiny.design/tiny-vue/zh-CN/os-theme/components/dialog-box#secondary-dialog
添加append-to-body 后无效
<tiny-dialog-box>
...
<tiny-dialog-box append-to-body>
</tiny-dialog-box>
</tiny-dialog-box>
这样试一下 @thestar077
<tiny-dialog-box> ... <tiny-dialog-box append-to-body> </tiny-dialog-box> </tiny-dialog-box>这样试一下 @thes给子弹窗增加 append-to-body是没有办法生效的,在官网上的那个我看也是有问题的,他的问题是当打开子弹窗再将子弹窗关闭之后,父弹窗的遮罩层失效
<tiny-dialog-box>
<tiny-dialog-box append-to-body >
</tiny-dialog-box>
</tiny-dialog-box>
原因: 1个 dialog-box是渲染在”原位“置的, 同时在document.body上,添加一个v-modal的遮罩层。 如果内部再添加一个 dialog-box, 那么 二级dailog-box渲染在第一个的内容区位置了, 同时递增 全局的v-modal的z-index层高。
由于v-modal层高增长,它会覆盖住第一个dialog-box, 一定会覆盖住第一个dialog-box的内容区位置了的。
解决办法: tiny-dialog-box 如上嵌套使用时, 属于”二级弹窗“, 参考官网的示例, 应该给内层的dialog-box 添加 append-to-body 才行。