济菏高速业务端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

223 lines
4.7 KiB

<template>
<Teleport>
<Transition name="fade">
<div :class="['mask-layer', { 'none-mask': noneMask }]" v-if="modelVisible">
<BackgroundClip class="dialog"
clipPath="polygon(calc(100% - var(--clip-width)) 0, 100% var(--clip-width), 100% 100%, var(--clip-width) 100%, 0 calc(100% - var(--clip-width)), 0 0)"
borderColor="linear-gradient(180deg, rgba(78, 174, 204, .9), rgba(78, 174, 204, 0))"
bgColor="linear-gradient(180deg, rgba(14, 69, 92, 0.9) 0%, rgba(20, 89, 119, 0.9) 100%)"
ref="DialogContentRef" :width="width" :top="top" :right="right">
<div class="dialog-title">
<img class="title-icon" src="@screen/images/dialog/title-icon.svg" />
<span>{{ title }}</span>
<img class="icon-close" @click.stop="modelVisible = false" src="@screen/images/dialog/icon-close.svg" />
</div>
<div class="dialog-content">
<slot />
</div>
<img class="bottom-right" src="@screen/images/dialog/right-bottom.svg" />
<div class="footer" v-if="$slots.footer">
<slot name="footer"></slot>
</div>
</BackgroundClip>
</div>
</Transition>
</Teleport>
</template>
<script>
import Teleport from "../Teleport.vue";
import BackgroundClip from "@screen/components/Decorations/BackgroundClip.vue";
import { moveable, stopPropagation } from "./utils";
export default {
components: {
Teleport,
BackgroundClip,
},
model: {
prop: "visible",
event: "update:value",
},
name: "Dialog",
props: {
width: {
type: String,
default: null,
},
top: {
type: String,
default: null,
},
right: {
type: String,
default: null,
},
title: {
type: String,
},
visible: Boolean,
noneMask: {
type: Boolean,
default: false,
},
},
watch: {
visible: {
deep: true,
handler(bool) {
this.$nextTick(() => {
if (!bool) return this.destroyMoveable?.();
const container = this.$refs.DialogContentRef.$el;
this.destroyMoveable = moveable(container, {
target: container.querySelector(".dialog-title"),
});
stopPropagation(container.querySelector(".dialog-title").lastChild);
this.$once("hook:beforeDestroy", () => this.destroyMoveable?.());
});
},
},
},
methods: {
updateDialogVisible(bool) {
this.modelVisible = bool;
},
},
mounted() {
this.emitter.on("updateDialogVisible", this.updateDialogVisible);
},
computed: {
modelVisible: {
get() {
return this.visible;
},
set(val) {
this.$emit("update:value", val);
},
},
},
beforeDestroy() {
this.modelVisible = false;
},
};
</script>
<style lang="scss" scoped>
.mask-layer {
position: fixed;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.36);
border-radius: 0px 0px 0px 0px;
z-index: 1100;
// display: flex;
// align-items: center;
// justify-content: center;
--border-width: 1px;
--clip-width-num: 24;
--clip-width: calc(var(--clip-width-num) * 1px);
}
.none-mask {
background: rgba(0, 0, 0, 0);
pointer-events: none;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.24s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.dialog {
max-width: 72vw;
opacity: 1;
background-clip: padding-box;
position: relative;
box-sizing: border-box;
top: 20%;
// margin: auto;
padding-bottom: 20px;
// margin: calc(var(--border-width) / 2);
pointer-events: all;
.dialog-title {
position: relative;
width: calc(100% - 2px);
height: 51px;
display: flex;
padding-top: 3px;
align-items: center;
justify-content: space-between;
background: linear-gradient(90deg, #267494 0%, rgba(38, 116, 148, 0) 100%);
font-size: 19px;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
color: #3de8ff;
.title-icon {
position: absolute;
top: -1px;
left: -1px;
height: 6px;
}
.icon-close {
cursor: pointer;
margin-right: 21px;
}
span {
margin-left: 20px;
height: 48px;
display: flex;
align-items: center;
}
}
.dialog-content {
padding: 9px 21px 27px 21px;
max-height: 75vh;
overflow-y: auto;
}
.bottom-right {
position: absolute;
right: 0;
bottom: 0;
}
.footer {
display: flex;
align-items: center;
gap: 9px;
width: 100%;
justify-content: flex-end;
margin-bottom: 21px;
padding: 0 27px;
::v-deep {
>div {
min-width: 96px;
}
}
// padding: 21px 36px;
// padding-top: 9px;
}
}
</style>