Blame view

ant-design-vue-jeecg/src/components/jeecg/JModal/JModal.vue 5.3 KB
肖超群 authored
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<template>
  <a-modal
    ref="modal"
    :class="getClass(modalClass)"
    :style="getStyle(modalStyle)"
    :visible="visible"
    v-bind="_attrs"
    v-on="$listeners"
    @ok="handleOk"
    @cancel="handleCancel"
    destroyOnClose
  >

    <slot></slot>
    <!--有设置标题-->
    <template v-if="!isNoTitle" slot="title">
      <a-row class="j-modal-title-row" type="flex">
        <a-col class="left">
          <slot name="title">{{ title }}</slot>
        </a-col>
        <a-col v-if="switchFullscreen" class="right" @click="toggleFullscreen">
          <a-button class="ant-modal-close ant-modal-close-x" ghost type="link" :icon="fullscreenButtonIcon"/>
        </a-col>
      </a-row>
    </template>
    <!--没有设置标题-->
    <template v-else slot="title">
      <a-row class="j-modal-title-row" type="flex">
        <a-col v-if="switchFullscreen" class="right" @click="toggleFullscreen">
          <a-button class="ant-modal-close ant-modal-close-x" ghost type="link" :icon="fullscreenButtonIcon"/>
        </a-col>
      </a-row>
    </template>

    <!-- 处理 scopedSlots -->
    <template v-for="slotName of scopedSlotsKeys" :slot="slotName">
      <slot :name="slotName"></slot>
    </template>

    <!-- 处理 slots -->
    <template v-for="slotName of slotsKeys" v-slot:[slotName]>
      <slot :name="slotName"></slot>
    </template>

  </a-modal>
</template>

<script>
肖超群 authored
50
51
import {getClass, getStyle} from '@/utils/props-util'
import {triggerWindowResizeEvent} from '@/utils/util'
肖超群 authored
52
53

export default {
肖超群 authored
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
  name: 'JModal',
  props: {
    title: String,
    // 可使用 .sync 修饰符
    visible: Boolean,
    // 是否全屏弹窗,当全屏时无论如何都会禁止 body 滚动。可使用 .sync 修饰符
    fullscreen: {
      type: Boolean,
      default: false
    },
    // 是否允许切换全屏(允许后右上角会出现一个按钮)
    switchFullscreen: {
      type: Boolean,
      default: false
    },
    // 点击确定按钮的时候是否关闭弹窗
    okClose: {
      type: Boolean,
      default: true
    },
  },
  data() {
    return {
      // 内部使用的 slots ,不再处理
      usedSlots: ['title'],
      // 实际控制是否全屏的参数
      innerFullscreen: this.fullscreen,
    }
  },
  computed: {
    // 一些未处理的参数或特殊处理的参数绑定到 a-modal 上
    _attrs() {
      let attrs = {...this.$attrs}
      // 如果全屏就将宽度设为 100%
      if (this.innerFullscreen) {
        attrs['width'] = '100%'
      }
      return attrs
    },
    modalClass() {
肖超群 authored
94
      return {
肖超群 authored
95
96
97
98
        'j-modal-box': true,
        'fullscreen': this.innerFullscreen,
        'no-title': this.isNoTitle,
        'no-footer': this.isNoFooter,
肖超群 authored
99
100
      }
    },
肖超群 authored
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    modalStyle() {
      let style = {}
      // 如果全屏就将top设为 0
      if (this.innerFullscreen) {
        style['top'] = '0'
      }
      return style
    },
    isNoTitle() {
      return !this.title && !this.allSlotsKeys.includes('title')
    },
    isNoFooter() {
      return this._attrs['footer'] === null
    },
    slotsKeys() {
      return Object.keys(this.$slots).filter(key => !this.usedSlots.includes(key))
    },
    scopedSlotsKeys() {
      return Object.keys(this.$scopedSlots).filter(key => !this.usedSlots.includes(key))
    },
    allSlotsKeys() {
      return Object.keys(this.$slots).concat(Object.keys(this.$scopedSlots))
    },
    // 切换全屏的按钮图标
    fullscreenButtonIcon() {
      return this.innerFullscreen ? 'fullscreen-exit' : 'fullscreen'
    },
  },
  watch: {
    visible() {
      if (this.visible) {
        this.innerFullscreen = this.fullscreen
      }
    },
    innerFullscreen(val) {
      this.$emit('update:fullscreen', val)
    },
  },
  methods: {

    getClass(clazz) {
      return {...getClass(this), ...clazz}
    },
    getStyle(style) {
      return {...getStyle(this), ...style}
    },

    close() {
      this.$emit('update:visible', false)
    },

    handleOk() {
      if (this.okClose) {
肖超群 authored
154
        this.close()
肖超群 authored
155
156
157
158
159
      }
    },
    handleCancel() {
      this.close()
    },
肖超群 authored
160
肖超群 authored
161
162
163
164
165
    /** 切换全屏 */
    toggleFullscreen() {
      this.innerFullscreen = !this.innerFullscreen
      triggerWindowResizeEvent()
    },
肖超群 authored
166
167

  }
肖超群 authored
168
}
肖超群 authored
169
170
171
</script>

<style lang="less">
肖超群 authored
172
173
174
175
176
177
178
179
180

.j-modal-box {
  &.fullscreen {
    top: 0;
    left: 0;
    padding: 0;

    // 兼容1.6.2版本的antdv
    & .ant-modal {
肖超群 authored
181
182
      top: 0;
      padding: 0;
肖超群 authored
183
184
      height: 100vh;
    }
肖超群 authored
185
肖超群 authored
186
187
188
    & .ant-modal-content {
      height: 100vh;
      border-radius: 0;
肖超群 authored
189
肖超群 authored
190
191
192
193
      & .ant-modal-body {
        /* title 和 footer 各占 55px */
        height: calc(100% - 55px - 55px);
        overflow: auto;
肖超群 authored
194
      }
肖超群 authored
195
    }
肖超群 authored
196
肖超群 authored
197
198
199
    &.no-title, &.no-footer {
      .ant-modal-body {
        height: calc(100% - 55px);
肖超群 authored
200
201
202
      }
    }
肖超群 authored
203
204
205
    &.no-title.no-footer {
      .ant-modal-body {
        height: 100%;
肖超群 authored
206
      }
肖超群 authored
207
208
    }
  }
肖超群 authored
209
肖超群 authored
210
211
212
213
214
215
216
217
  .j-modal-title-row {
    .left {
      width: calc(100% - 56px - 56px);
    }

    .right {
      width: 56px;
      position: inherit;
肖超群 authored
218
肖超群 authored
219
220
221
      .ant-modal-close {
        right: 56px;
        color: rgba(0, 0, 0, 0.45);
肖超群 authored
222
肖超群 authored
223
224
        &:hover {
          color: rgba(0, 0, 0, 0.75);
肖超群 authored
225
226
227
228
229
        }
      }
    }
  }
肖超群 authored
230
231
232
233
  &.no-title {
    .ant-modal-header {
      padding: 0px 24px;
      border-bottom: 0px !important;
肖超群 authored
234
235
    }
  }
肖超群 authored
236
237
238
239
240
241
242
243
}

@media (max-width: 767px) {
  .j-modal-box.fullscreen {
    margin: 0;
    max-width: 100vw;
  }
}
肖超群 authored
244
</style>