Commit 7eb0fb1655b38387991f3a9d00658fcba961881e

Authored by xingyu
1 parent 91abae88

fix: close modal

yudao-ui-admin-vue3/src/components/Cropper/src/CopperModal.vue
1 1 <template>
2   - <Dialog
3   - v-model="dialogVisible"
4   - :title="t('cropper.modalTitle')"
5   - width="800px"
6   - maxHeight="380px"
7   - :canFullscreen="false"
8   - >
9   - <div :class="prefixCls">
10   - <div :class="`${prefixCls}-left`">
11   - <div :class="`${prefixCls}-cropper`">
12   - <CropperImage
13   - v-if="src"
14   - :src="src"
15   - height="300px"
16   - :circled="circled"
17   - @cropend="handleCropend"
18   - @ready="handleReady"
19   - />
20   - </div>
  2 + <div>
  3 + <Dialog
  4 + v-model="dialogVisible"
  5 + :title="t('cropper.modalTitle')"
  6 + width="800px"
  7 + maxHeight="380px"
  8 + :canFullscreen="false"
  9 + >
  10 + <div :class="prefixCls">
  11 + <div :class="`${prefixCls}-left`">
  12 + <div :class="`${prefixCls}-cropper`">
  13 + <CropperImage
  14 + v-if="src"
  15 + :src="src"
  16 + height="300px"
  17 + :circled="circled"
  18 + @cropend="handleCropend"
  19 + @ready="handleReady"
  20 + />
  21 + </div>
21 22  
22   - <div :class="`${prefixCls}-toolbar`">
23   - <el-upload :fileList="[]" accept="image/*" :beforeUpload="handleBeforeUpload">
24   - <el-tooltip :content="t('cropper.selectImage')" placement="bottom">
25   - <XButton preIcon="ant-design:upload-outlined" type="primary" />
26   - </el-tooltip>
27   - </el-upload>
28   - <el-space>
29   - <el-tooltip :content="t('cropper.btn_reset')" placement="bottom">
30   - <XButton
31   - type="primary"
32   - preIcon="ant-design:reload-outlined"
33   - size="small"
34   - :disabled="!src"
35   - @click="handlerToolbar('reset')"
36   - />
37   - </el-tooltip>
38   - <el-tooltip :content="t('cropper.btn_rotate_left')" placement="bottom">
39   - <XButton
40   - type="primary"
41   - preIcon="ant-design:rotate-left-outlined"
42   - size="small"
43   - :disabled="!src"
44   - @click="handlerToolbar('rotate', -45)"
45   - />
46   - </el-tooltip>
47   - <el-tooltip :content="t('cropper.btn_rotate_right')" placement="bottom">
48   - <XButton
49   - type="primary"
50   - preIcon="ant-design:rotate-right-outlined"
51   - size="small"
52   - :disabled="!src"
53   - @click="handlerToolbar('rotate', 45)"
54   - />
55   - </el-tooltip>
56   - <el-tooltip :content="t('cropper.btn_scale_x')" placement="bottom">
57   - <XButton
58   - type="primary"
59   - preIcon="vaadin:arrows-long-h"
60   - size="small"
61   - :disabled="!src"
62   - @click="handlerToolbar('scaleX')"
63   - />
64   - </el-tooltip>
65   - <el-tooltip :content="t('cropper.btn_scale_y')" placement="bottom">
66   - <XButton
67   - type="primary"
68   - preIcon="vaadin:arrows-long-v"
69   - size="small"
70   - :disabled="!src"
71   - @click="handlerToolbar('scaleY')"
72   - />
73   - </el-tooltip>
74   - <el-tooltip :content="t('cropper.btn_zoom_in')" placement="bottom">
75   - <XButton
76   - type="primary"
77   - preIcon="ant-design:zoom-in-outlined"
78   - size="small"
79   - :disabled="!src"
80   - @click="handlerToolbar('zoom', 0.1)"
81   - />
82   - </el-tooltip>
83   - <el-tooltip :content="t('cropper.btn_zoom_out')" placement="bottom">
84   - <XButton
85   - type="primary"
86   - preIcon="ant-design:zoom-out-outlined"
87   - size="small"
88   - :disabled="!src"
89   - @click="handlerToolbar('zoom', -0.1)"
90   - />
91   - </el-tooltip>
92   - </el-space>
93   - </div>
94   - </div>
95   - <div :class="`${prefixCls}-right`">
96   - <div :class="`${prefixCls}-preview`">
97   - <img :src="previewSource" v-if="previewSource" :alt="t('cropper.preview')" />
  23 + <div :class="`${prefixCls}-toolbar`">
  24 + <el-upload :fileList="[]" accept="image/*" :beforeUpload="handleBeforeUpload">
  25 + <el-tooltip :content="t('cropper.selectImage')" placement="bottom">
  26 + <XButton preIcon="ant-design:upload-outlined" type="primary" />
  27 + </el-tooltip>
  28 + </el-upload>
  29 + <el-space>
  30 + <el-tooltip :content="t('cropper.btn_reset')" placement="bottom">
  31 + <XButton
  32 + type="primary"
  33 + preIcon="ant-design:reload-outlined"
  34 + size="small"
  35 + :disabled="!src"
  36 + @click="handlerToolbar('reset')"
  37 + />
  38 + </el-tooltip>
  39 + <el-tooltip :content="t('cropper.btn_rotate_left')" placement="bottom">
  40 + <XButton
  41 + type="primary"
  42 + preIcon="ant-design:rotate-left-outlined"
  43 + size="small"
  44 + :disabled="!src"
  45 + @click="handlerToolbar('rotate', -45)"
  46 + />
  47 + </el-tooltip>
  48 + <el-tooltip :content="t('cropper.btn_rotate_right')" placement="bottom">
  49 + <XButton
  50 + type="primary"
  51 + preIcon="ant-design:rotate-right-outlined"
  52 + size="small"
  53 + :disabled="!src"
  54 + @click="handlerToolbar('rotate', 45)"
  55 + />
  56 + </el-tooltip>
  57 + <el-tooltip :content="t('cropper.btn_scale_x')" placement="bottom">
  58 + <XButton
  59 + type="primary"
  60 + preIcon="vaadin:arrows-long-h"
  61 + size="small"
  62 + :disabled="!src"
  63 + @click="handlerToolbar('scaleX')"
  64 + />
  65 + </el-tooltip>
  66 + <el-tooltip :content="t('cropper.btn_scale_y')" placement="bottom">
  67 + <XButton
  68 + type="primary"
  69 + preIcon="vaadin:arrows-long-v"
  70 + size="small"
  71 + :disabled="!src"
  72 + @click="handlerToolbar('scaleY')"
  73 + />
  74 + </el-tooltip>
  75 + <el-tooltip :content="t('cropper.btn_zoom_in')" placement="bottom">
  76 + <XButton
  77 + type="primary"
  78 + preIcon="ant-design:zoom-in-outlined"
  79 + size="small"
  80 + :disabled="!src"
  81 + @click="handlerToolbar('zoom', 0.1)"
  82 + />
  83 + </el-tooltip>
  84 + <el-tooltip :content="t('cropper.btn_zoom_out')" placement="bottom">
  85 + <XButton
  86 + type="primary"
  87 + preIcon="ant-design:zoom-out-outlined"
  88 + size="small"
  89 + :disabled="!src"
  90 + @click="handlerToolbar('zoom', -0.1)"
  91 + />
  92 + </el-tooltip>
  93 + </el-space>
  94 + </div>
98 95 </div>
99   - <template v-if="previewSource">
100   - <div :class="`${prefixCls}-group`">
101   - <el-avatar :src="previewSource" size="large" />
102   - <el-avatar :src="previewSource" :size="48" />
103   - <el-avatar :src="previewSource" :size="64" />
104   - <el-avatar :src="previewSource" :size="80" />
  96 + <div :class="`${prefixCls}-right`">
  97 + <div :class="`${prefixCls}-preview`">
  98 + <img :src="previewSource" v-if="previewSource" :alt="t('cropper.preview')" />
105 99 </div>
106   - </template>
  100 + <template v-if="previewSource">
  101 + <div :class="`${prefixCls}-group`">
  102 + <el-avatar :src="previewSource" size="large" />
  103 + <el-avatar :src="previewSource" :size="48" />
  104 + <el-avatar :src="previewSource" :size="64" />
  105 + <el-avatar :src="previewSource" :size="80" />
  106 + </div>
  107 + </template>
  108 + </div>
107 109 </div>
108   - </div>
109   - <template #footer>
110   - <el-button type="primary" @click="handleOk">{{ t('cropper.okText') }}</el-button>
111   - </template>
112   - </Dialog>
  110 + <template #footer>
  111 + <el-button type="primary" @click="handleOk">{{ t('cropper.okText') }}</el-button>
  112 + </template>
  113 + </Dialog>
  114 + </div>
113 115 </template>
114 116 <script setup lang="ts">
115 117 import { useDesign } from '@/hooks/web/useDesign'
... ... @@ -173,7 +175,6 @@ function handlerToolbar(event: string, arg?: number) {
173 175 async function handleOk() {
174 176 const blob = dataURLtoBlob(previewSource.value)
175 177 emit('uploadSuccess', { source: previewSource.value, data: blob, filename: filename })
176   - closeModal()
177 178 }
178 179 function openModal() {
179 180 dialogVisible.value = true
... ...
yudao-ui-admin-vue3/src/components/Cropper/src/CropperAvatar.vue
... ... @@ -4,7 +4,11 @@
4 4 <el-button :class="`${prefixCls}-upload-btn`" @click="open()" v-if="showBtn">
5 5 {{ btnText ? btnText : t('cropper.selectImage') }}
6 6 </el-button>
7   - <CopperModal ref="cropperModel" @upload-success="handleUploadSuccess" :srcValue="sourceValue" />
  7 + <CopperModal
  8 + ref="cropperModelRef"
  9 + @upload-success="handleUploadSuccess"
  10 + :srcValue="sourceValue"
  11 + />
8 12 </div>
9 13 </template>
10 14 <script setup lang="ts">
... ... @@ -29,7 +33,7 @@ const prefixCls = getPrefixCls(&#39;cropper-avatar&#39;)
29 33 const message = useMessage()
30 34 const { t } = useI18n()
31 35  
32   -const cropperModel = ref()
  36 +const cropperModelRef = ref()
33 37  
34 38 watchEffect(() => {
35 39 sourceValue.value = props.value
... ... @@ -49,8 +53,15 @@ function handleUploadSuccess({ source, data, filename }) {
49 53 }
50 54  
51 55 function open() {
52   - cropperModel.value.openModal()
  56 + cropperModelRef.value.openModal()
53 57 }
  58 +function close() {
  59 + cropperModelRef.value.closeModal()
  60 +}
  61 +defineExpose({
  62 + open,
  63 + close
  64 +})
54 65 </script>
55 66 <style lang="scss" scoped>
56 67 $prefix-cls: #{$namespace}--cropper-avatar;
... ...
yudao-ui-admin-vue3/src/views/Profile/components/UserAvatar.vue
1 1 <template>
2 2 <div class="change-avatar">
3 3 <CropperAvatar
  4 + ref="cropperRef"
4 5 :value="avatar"
5 6 :showBtn="false"
6 7 @change="handelUpload"
... ... @@ -10,7 +11,7 @@
10 11 </div>
11 12 </template>
12 13 <script setup lang="ts">
13   -import { computed } from 'vue'
  14 +import { computed, ref } from 'vue'
14 15 import { propTypes } from '@/utils/propTypes'
15 16 import { CropperAvatar } from '@/components/Cropper'
16 17 import { uploadAvatarApi } from '@/api/system/user/profile'
... ... @@ -21,8 +22,10 @@ const avatar = computed(() =&gt; {
21 22 return props.img
22 23 })
23 24  
  25 +const cropperRef = ref()
24 26 const handelUpload = async ({ data }) => {
25 27 await uploadAvatarApi({ avatarFile: data })
  28 + cropperRef.value.close()
26 29 }
27 30 </script>
28 31  
... ...