mirror of https://github.com/halo-dev/halo-admin
feat: add layer-closeable prop for modal (#861)
#### What type of PR is this? /kind feature #### What this PR does / why we need it: VModal 组件支持设置是否允许点击蒙层以关闭模态框,并将所有包含表单的模态框设置为不允许点击蒙层关闭。 #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/3328 #### Screenshots: ![2023-02-17 12 08 56](https://user-images.githubusercontent.com/21301288/219547318-d7c59742-8546-4bc8-9d49-fcff4053602f.gif) #### Special notes for your reviewer: 测试方式: 1. 打开 Console 端任意一个表单模态框,测试点击表单外部区域是否会关闭弹框。 #### Does this PR introduce a user-facing change? ```release-note 优化 Console 端部分包含表单的模态框,默认不允许点击外部区域关闭模态框。 ```pull/841/head^2
parent
fad0dcc3ba
commit
c8dbd2422c
|
@ -90,7 +90,12 @@ const handleClose = () => {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<VModal :visible="visible" :width="450" @close="handleCancel()">
|
||||
<VModal
|
||||
:visible="visible"
|
||||
:width="450"
|
||||
:layer-closable="true"
|
||||
@close="handleCancel()"
|
||||
>
|
||||
<div class="flex justify-between items-start py-2 mb-2">
|
||||
<div class="flex flex-row items-center gap-3">
|
||||
<component
|
||||
|
|
|
@ -12,6 +12,7 @@ const props = withDefaults(
|
|||
bodyClass?: string[];
|
||||
mountToBody?: boolean;
|
||||
centered?: boolean;
|
||||
layerClosable?: boolean;
|
||||
}>(),
|
||||
{
|
||||
visible: false,
|
||||
|
@ -22,6 +23,7 @@ const props = withDefaults(
|
|||
bodyClass: undefined,
|
||||
mountToBody: false,
|
||||
centered: true,
|
||||
layerClosable: false,
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -52,6 +54,19 @@ function handleClose() {
|
|||
emit("close");
|
||||
}
|
||||
|
||||
const focus = ref(false);
|
||||
|
||||
function handleClickLayer() {
|
||||
if (props.layerClosable) {
|
||||
handleClose();
|
||||
return;
|
||||
}
|
||||
focus.value = true;
|
||||
setTimeout(() => {
|
||||
focus.value = false;
|
||||
}, 300);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.visible,
|
||||
() => {
|
||||
|
@ -85,7 +100,11 @@ watch(
|
|||
@before-enter="rootVisible = true"
|
||||
@after-leave="rootVisible = false"
|
||||
>
|
||||
<div v-show="visible" class="modal-layer" @click.stop="handleClose()" />
|
||||
<div
|
||||
v-show="visible"
|
||||
class="modal-layer"
|
||||
@click.stop="handleClickLayer()"
|
||||
/>
|
||||
</transition>
|
||||
<transition
|
||||
enter-active-class="ease-out duration-200"
|
||||
|
@ -98,7 +117,8 @@ watch(
|
|||
<div
|
||||
v-show="visible"
|
||||
:style="contentStyles"
|
||||
class="modal-content transform transition-all"
|
||||
class="modal-content transform transition-all duration-300"
|
||||
:class="{ 'modal-focus': focus }"
|
||||
>
|
||||
<div v-if="$slots.header || title" class="modal-header group">
|
||||
<slot name="header">
|
||||
|
@ -163,6 +183,10 @@ watch(
|
|||
width: calc(100vw - 20px);
|
||||
max-height: calc(100vh - 5rem);
|
||||
|
||||
&.modal-focus {
|
||||
@apply scale-[1.02];
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
@apply flex
|
||||
justify-between
|
||||
|
|
|
@ -372,6 +372,7 @@ const onVisibleChange = (visible: boolean) => {
|
|||
:mount-to-body="true"
|
||||
:width="650"
|
||||
:centered="false"
|
||||
:layer-closable="true"
|
||||
@update:visible="onVisibleChange"
|
||||
>
|
||||
<div id="search-input" class="border-b border-gray-100 px-4 py-2.5">
|
||||
|
|
|
@ -32,6 +32,7 @@ const onVisibleChange = (visible: boolean) => {
|
|||
:visible="visible"
|
||||
fullscreen
|
||||
:title="title"
|
||||
:layer-closable="true"
|
||||
@update:visible="onVisibleChange"
|
||||
>
|
||||
<template #actions>
|
||||
|
|
|
@ -75,6 +75,7 @@ const onVisibleChange = (visible: boolean) => {
|
|||
:visible="visible"
|
||||
:width="1000"
|
||||
:mount-to-body="mountToBody"
|
||||
:layer-closable="true"
|
||||
height="calc(100vh - 20px)"
|
||||
@update:visible="onVisibleChange"
|
||||
>
|
||||
|
|
|
@ -122,6 +122,7 @@ watch(
|
|||
:width="750"
|
||||
title="存储策略"
|
||||
:body-class="['!p-0']"
|
||||
:layer-closable="true"
|
||||
@update:visible="onVisibleChange"
|
||||
>
|
||||
<template #actions>
|
||||
|
|
|
@ -87,6 +87,7 @@ const handleConfirm = () => {
|
|||
:visible="visible"
|
||||
:width="1240"
|
||||
:mount-to-body="true"
|
||||
:layer-closable="true"
|
||||
title="选择附件"
|
||||
height="calc(100vh - 20px)"
|
||||
@update:visible="onVisibleChange"
|
||||
|
|
|
@ -29,6 +29,7 @@ const onVisibleChange = (visible: boolean) => {
|
|||
<VModal
|
||||
:body-class="['!p-0']"
|
||||
:visible="visible"
|
||||
:layer-closable="true"
|
||||
fullscreen
|
||||
title="文章预览"
|
||||
@update:visible="onVisibleChange"
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
v-model:visible="widgetsModal"
|
||||
height="calc(100vh - 20px)"
|
||||
:width="1280"
|
||||
:layer-closable="true"
|
||||
title="小组件"
|
||||
>
|
||||
<VTabbar
|
||||
|
|
Loading…
Reference in New Issue