|
- <template>
- <transition name="fade">
- <div
- v-if="isDialogExist"
- class="shade flex-box fullscreen"
- :style="styleData"
- >
- <div
- class="dialog-area"
- :class="{
- 'pl-54': isFullscreen && !opened,
- 'pl-210': isFullscreen && opened,
- 'ml-210': !isFullscreen && isLargeWidth && opened
- }"
- >
- <div class="title-area">
- <slot name="title">
- <span class="title">
- {{ title }}
- </span>
-
- <span v-if="subTitle.length > 0" class="sub-title">
- • {{ subTitle }}
- </span>
- </slot>
- <div class="icon-area ml-auto">
- <i class="el-icon-minus pointer" />
- <svg-icon
- v-if="!isFullscreen"
- icon-class="fullscreen"
- class="change-fullscreen-icon pointer"
- @click="fullscreen"
- />
- <svg-icon
- v-else
- icon-class="exit-fullscreen"
- class="change-fullscreen-icon pointer"
- @click="exitFullscreen"
- />
- <i class="el-icon-close pointer" @click="handleClose" />
- </div>
- </div>
- <div class="slot-place">
- <slot />
- </div>
- <div class="footer flex-box">
- <slot name="footer"></slot>
- </div>
- </div>
- </div>
- </transition>
- </template>
-
- <script>
- export default {
- name: 'Index',
- props: {
- isDialogExist: {
- type: Boolean,
- default: false
- },
- isDefaultFull: {
- type: Boolean,
- default: false
- },
- title: {
- type: String,
- default: '标题'
- },
- subTitle: {
- type: String,
- default: ''
- },
- dialogStyle: { type: Object, default: () => ({}), require: true }
- },
- data() {
- return {
- isFullscreen: false,
- styleData: {},
- styleTmp: {}
- }
- },
- computed: {
- opened() {
- return this.$store.state.app.sidebar.opened
- },
- isLargeWidth() {
- const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
- return parseInt(this.dialogStyle['--dialog-width']) >= vw - 420
- }
- },
- watch: {
- isDialogExist(n) {
- this.$nextTick(() => {
- if (n === true) { // 弹窗打开时
- // 检测到默认全屏时
- if (this.isDefaultFull) {
- this.fullscreen()
- }
- this.handleDialogDimension()
- window.addEventListener('resize', this.handleDialogDimension)
- } else {
- window.removeEventListener('resize', this.handleDialogDimension)
- // 关闭窗口时重置回原来的值
- this.$set(this.styleData, '--dialog-height', this.dialogStyle['--dialog-height'])
- this.$set(this.styleData, '--dialog-width', this.dialogStyle['--dialog-width'])
- }
- })
- }
- },
- created() {
- this.styleData = JSON.parse(JSON.stringify(this.dialogStyle))
- if (this.isDefaultFull) {
- this.fullscreen()
- }
- },
- methods: {
- handleDialogDimension() {
- /* if (this.styleData['--dialog-height'] === 'auto') {
- // 如果是auto,转为实际的高度
- this.styleData['--dialog-height'] = this.$el.offsetHeight
- }*/
- if (this.isFullscreen) {
- return false
- }
- // 视窗高度 document.documentElement.clientHeight(不含滚动条),window.innerHeight(含滚动条)
- const vh = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0)
- // 宽度也一样处理
- const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
-
- // 弹窗高度大于或等于视窗高度
- if (parseInt(this.dialogStyle['--dialog-height']) >= vh) {
- this.$set(this.styleData, '--dialog-height', 0.9 * vh + 'px')
- } else {
- // 没有超过,恢复原值
- this.$set(this.styleData, '--dialog-height', this.dialogStyle['--dialog-height'])
- }
-
- if (parseInt(this.dialogStyle['--dialog-width']) >= vw - 420) {
- this.$set(this.styleData, '--dialog-width', 0.9 * vw + 'px')
- } else {
- // 没有超过,恢复原值
- this.$set(this.styleData, '--dialog-width', this.dialogStyle['--dialog-width'])
- }
- },
- fullscreen() {
- this.styleTmp = this.dialogStyle
- this.styleData = {
- '--dialog-width': '100vw',
- '--dialog-height': '100vh',
- '--dialog-border-radius': 0,
- '--title-height': this.dialogStyle['--title-height'],
- '--footer-height': this.dialogStyle['--footer-height'],
- '--offset': '64px'
- }
- this.isFullscreen = true
- this.$emit('fullscreen')
- },
- exitFullscreen() {
- this.styleData = JSON.parse(JSON.stringify(this.styleTmp))
- this.styleData['--offset'] = '0px'
- this.isFullscreen = false
- this.$emit('exitFullscreen')
-
- this.handleDialogDimension()
- },
- handleClose() {
- // 重置回原尺寸
- this.styleData = JSON.parse(JSON.stringify(this.dialogStyle))
- // 退出全屏
- this.isFullscreen = false
- this.$emit('close-dialog')
- }
- }
- }
- </script>
-
- <style lang="scss" scoped>
- .shade {
- --dialog-width: 0;
- --dialog-height: 0;
- --dialog-border-radius: 15px;
- --title-height: 0;
- --footer-height: 0px;
- --offset: 0px;
-
- position: fixed;
- top: 0;
- left: 0;
- background-color: rgba(0, 0, 0, 0.2);
- z-index: 999;
-
- .pl-54 {
- padding-left: 54px;
- }
-
- .pl-210 {
- padding-left: 210px;
- margin-top: 128px;
-
- .slot-place {
- height: calc(
- var(--dialog-height) - var(--title-height) - var(--footer-height) -
- var(--offset)
- ) !important;
- }
- }
-
- .ml-210 {
- margin-left: 210px !important;
- }
-
- .dialog-area {
- overflow: hidden;
- width: var(--dialog-width);
- height: var(--dialog-height);
- border-radius: var(--dialog-border-radius);
- background-color: #fff;
- box-shadow: 1px 1px 50px 0 rgba(0, 0, 0, 0.3);
- transition: all 0.3s;
- animation: enter 0.3s;
-
- @keyframes enter {
- 0% {
- opacity: 0;
- transform: translateY(-27px);
- }
- 100% {
- opacity: 1;
- transform: translateY(0);
- }
- }
-
- .title-area {
- display: flex;
- align-items: center;
- height: var(--title-height);
- background-color: #F9F9F9;
-
-
- .title {
- margin-left: 24px;
- font: 400 15px PingFangSC-Regular, PingFang SC;
- color: #333;
- }
-
- .sub-title {
- margin-left: 5px;
- font: 400 15px PingFangSC-Regular, PingFang SC;
- color: #FF4242;
- }
-
- .icon-area {
- width: 102px;
-
- .change-fullscreen-icon {
- margin: 0 20px 0 17px;
- color: #333;
- }
- }
- }
-
- .slot-place {
- overflow: auto;
- position: relative;
- width: 100%;
- height: calc(
- var(--dialog-height) - var(--title-height) - var(--footer-height)
- );
- border: 0 solid transparent;
- }
- }
- }
-
- .fade-enter-active,
- .fade-leave-active {
- transition: opacity 0.2s;
- }
-
- .fade-enter,
- .fade-leave-to {
- opacity: 0;
- }
-
- .footer {
- box-shadow: 0px -2px 4px 0px rgba(0, 0, 0, 0.04);
- padding: 12px;
- justify-content: center;
- align-content: center;
- text-align: center;
- height: var(--footer-height);
- }
- </style>
|