hy-app 0.3.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -3
- package/common/shakeService.ts +31 -29
- package/components/hy-action-sheet/hy-action-sheet.vue +71 -46
- package/components/hy-address-picker/hy-address-picker.vue +94 -83
- package/components/hy-address-picker/index.scss +1 -1
- package/components/hy-avatar/hy-avatar.vue +87 -91
- package/components/hy-avatar/index.scss +1 -1
- package/components/hy-back-top/index.scss +1 -1
- package/components/hy-badge/hy-badge.vue +47 -46
- package/components/hy-button/hy-button.vue +117 -93
- package/components/hy-button/index.scss +2 -2
- package/components/hy-calendar/header.vue +11 -11
- package/components/hy-calendar/hy-calendar.vue +168 -160
- package/components/hy-calendar/index.scss +25 -25
- package/components/hy-calendar/month.vue +18 -19
- package/components/hy-card/hy-card.vue +55 -50
- package/components/hy-card/index.scss +11 -9
- package/components/hy-card/typing.d.ts +33 -32
- package/components/hy-cell/hy-cell.vue +81 -59
- package/components/hy-cell/index.scss +15 -15
- package/components/hy-check-button/hy-check-button.vue +54 -47
- package/components/hy-checkbox/hy-checkbox.vue +103 -111
- package/components/hy-checkbox/index.scss +24 -23
- package/components/hy-code-input/hy-code-input.vue +80 -89
- package/components/hy-config-provider/hy-config-provider.vue +19 -20
- package/components/hy-count-down/hy-count-down.vue +66 -67
- package/components/hy-count-to/hy-count-to.vue +105 -99
- package/components/hy-count-to/typing.d.ts +13 -12
- package/components/hy-datetime-picker/hy-datetime-picker.vue +261 -253
- package/components/hy-datetime-picker/typing.d.ts +42 -40
- package/components/hy-divider/hy-divider.vue +68 -73
- package/components/hy-dropdown/hy-dropdown.vue +20 -19
- package/components/hy-dropdown-item/hy-dropdown-item.vue +66 -61
- package/components/hy-dropdown-item/typing.d.ts +9 -9
- package/components/hy-empty/hy-empty.vue +53 -50
- package/components/hy-empty/icon.ts +32 -58
- package/components/hy-empty/index.scss +2 -2
- package/components/hy-empty/typing.d.ts +48 -35
- package/components/hy-flex/hy-flex.vue +52 -26
- package/components/hy-float-button/hy-float-button.vue +218 -210
- package/components/hy-folding-panel/hy-folding-panel.vue +32 -33
- package/components/hy-form/hy-form.vue +264 -259
- package/components/hy-grid/hy-grid.vue +44 -43
- package/components/hy-icon/hy-icon.vue +61 -67
- package/components/hy-image/hy-image.vue +112 -88
- package/components/hy-image/typing.d.ts +27 -23
- package/components/hy-input/hy-input.vue +157 -127
- package/components/hy-input/typing.d.ts +53 -47
- package/components/hy-line/hy-line.vue +26 -26
- package/components/hy-line-progress/hy-line-progress.vue +42 -35
- package/components/hy-list/hy-list.vue +76 -85
- package/components/hy-loading/hy-loading.vue +26 -23
- package/components/hy-menu/hy-menu.vue +48 -43
- package/components/hy-menu/typing.d.ts +18 -17
- package/components/hy-modal/hy-modal.vue +39 -35
- package/components/hy-navbar/hy-navbar.vue +25 -25
- package/components/hy-navbar/typing.d.ts +24 -22
- package/components/hy-notice-bar/hy-column-notice.vue +2 -2
- package/components/hy-notice-bar/hy-notice-bar.vue +26 -27
- package/components/hy-notice-bar/hy-row-notice.vue +1 -1
- package/components/hy-notice-bar/index.scss +6 -0
- package/components/hy-notify/hy-notify.vue +53 -53
- package/components/hy-number-step/hy-number-step.vue +134 -146
- package/components/hy-number-step/typing.d.ts +35 -35
- package/components/hy-overlay/hy-overlay.vue +23 -21
- package/components/hy-pagination/hy-pagination.vue +41 -36
- package/components/hy-picker/hy-picker.vue +184 -154
- package/components/hy-picker/typing.d.ts +39 -39
- package/components/hy-popover/hy-popover.vue +97 -77
- package/components/hy-popover/index.scss +3 -3
- package/components/hy-popup/hy-popup.vue +107 -98
- package/components/hy-price/hy-price.vue +38 -34
- package/components/hy-qrcode/hy-qrcode.vue +50 -51
- package/components/hy-radio/hy-radio.vue +101 -113
- package/components/hy-rate/hy-rate.vue +107 -88
- package/components/hy-read-more/hy-read-more.vue +64 -49
- package/components/hy-scroll-list/hy-scroll-list.vue +45 -48
- package/components/hy-search/hy-search.vue +75 -75
- package/components/hy-search/typing.d.ts +36 -35
- package/components/hy-signature/hy-signature.vue +282 -240
- package/components/hy-slider/hy-slider.vue +194 -152
- package/components/hy-slider/typing.d.ts +21 -21
- package/components/hy-steps/hy-steps.vue +118 -90
- package/components/hy-steps/index.scss +31 -21
- package/components/hy-submit-bar/hy-submit-bar.vue +61 -70
- package/components/hy-subsection/hy-subsection.vue +99 -102
- package/components/hy-subsection/typing.d.ts +19 -19
- package/components/hy-swipe-action/hy-swipe-action.vue +131 -118
- package/components/hy-swiper/hy-swiper.vue +85 -71
- package/components/hy-switch/hy-switch.vue +67 -72
- package/components/hy-switch/typing.d.ts +21 -19
- package/components/hy-tabs/hy-tabs.vue +168 -113
- package/components/hy-tag/hy-tag.vue +91 -87
- package/components/hy-tag/index.scss +13 -12
- package/components/hy-tag/typing.d.ts +26 -21
- package/components/hy-text/hy-text.vue +119 -111
- package/components/hy-textarea/hy-textarea.vue +100 -93
- package/components/hy-textarea/typing.d.ts +36 -31
- package/components/hy-toast/hy-toast.vue +77 -67
- package/components/hy-tooltip/hy-tooltip.vue +109 -91
- package/components/hy-transition/hy-transition.vue +62 -66
- package/components/hy-upload/hy-upload.vue +289 -154
- package/components/hy-upload/typing.d.ts +62 -36
- package/components/hy-warn/hy-warn.vue +34 -27
- package/components/hy-waterfall/hy-waterfall.vue +83 -74
- package/components/hy-watermark/hy-watermark.vue +134 -115
- package/composables/usePopover.ts +236 -221
- package/composables/useQueue.ts +53 -52
- package/libs/css/mixin.scss +4 -1
- package/libs/css/vars.css +2 -0
- package/package.json +2 -2
- package/store/index.ts +9 -1
- package/theme.scss +1 -0
- package/typing/index.ts +0 -1
- package/typing/modules/common.d.ts +0 -2
- package/web-types.json +1 -1
|
@@ -2,7 +2,11 @@
|
|
|
2
2
|
<view class="hy-upload" :style="[customStyle]">
|
|
3
3
|
<view class="hy-upload__wrap">
|
|
4
4
|
<template v-if="previewImage">
|
|
5
|
-
<view
|
|
5
|
+
<view
|
|
6
|
+
class="hy-upload__wrap__preview"
|
|
7
|
+
v-for="(item, index) in lists"
|
|
8
|
+
:key="index"
|
|
9
|
+
>
|
|
6
10
|
<image
|
|
7
11
|
v-if="item.isImage || (item.type && item.type === 'image')"
|
|
8
12
|
:src="item.thumb || item.url"
|
|
@@ -16,14 +20,26 @@
|
|
|
16
20
|
},
|
|
17
21
|
]"
|
|
18
22
|
/>
|
|
19
|
-
<view
|
|
20
|
-
|
|
23
|
+
<view
|
|
24
|
+
v-else
|
|
25
|
+
class="hy-upload__wrap__preview__other"
|
|
26
|
+
@tap="onClickPreview(item, index)"
|
|
27
|
+
>
|
|
28
|
+
<HyIcon
|
|
21
29
|
color="#80CBF9"
|
|
22
30
|
size="26"
|
|
23
|
-
:name="
|
|
24
|
-
|
|
31
|
+
:name="
|
|
32
|
+
item.isVideo || (item.type && item.type === 'video')
|
|
33
|
+
? 'movie'
|
|
34
|
+
: 'folder'
|
|
35
|
+
"
|
|
36
|
+
></HyIcon>
|
|
25
37
|
<text class="hy-upload__wrap__preview__other__text">
|
|
26
|
-
{{
|
|
38
|
+
{{
|
|
39
|
+
item.isVideo || (item.type && item.type === "video")
|
|
40
|
+
? "视频"
|
|
41
|
+
: "文件"
|
|
42
|
+
}}
|
|
27
43
|
</text>
|
|
28
44
|
</view>
|
|
29
45
|
|
|
@@ -46,7 +62,11 @@
|
|
|
46
62
|
@tap.stop="deleteItem(index)"
|
|
47
63
|
>
|
|
48
64
|
<view class="hy-upload__deletable__icon">
|
|
49
|
-
<HyIcon
|
|
65
|
+
<HyIcon
|
|
66
|
+
:name="IconConfig.CLOSE"
|
|
67
|
+
color="#ffffff"
|
|
68
|
+
size="14"
|
|
69
|
+
></HyIcon>
|
|
50
70
|
</view>
|
|
51
71
|
</view>
|
|
52
72
|
<!-- 删除图片图标 -->
|
|
@@ -55,7 +75,11 @@
|
|
|
55
75
|
<view class="hy-upload__success" v-if="item.status === 'success'">
|
|
56
76
|
<!-- #ifndef APP-NVUE -->
|
|
57
77
|
<view class="hy-upload__success__icon">
|
|
58
|
-
<HyIcon
|
|
78
|
+
<HyIcon
|
|
79
|
+
:name="IconConfig.CHECK_MASK"
|
|
80
|
+
color="#ffffff"
|
|
81
|
+
size="12"
|
|
82
|
+
></HyIcon>
|
|
59
83
|
</view>
|
|
60
84
|
<!-- #endif -->
|
|
61
85
|
</view>
|
|
@@ -87,8 +111,14 @@
|
|
|
87
111
|
},
|
|
88
112
|
]"
|
|
89
113
|
>
|
|
90
|
-
<HyIcon
|
|
91
|
-
|
|
114
|
+
<HyIcon
|
|
115
|
+
:name="uploadIcon"
|
|
116
|
+
size="26"
|
|
117
|
+
:color="uploadIconColor"
|
|
118
|
+
></HyIcon>
|
|
119
|
+
<text v-if="uploadText" class="hy-upload__button__text">{{
|
|
120
|
+
uploadText
|
|
121
|
+
}}</text>
|
|
92
122
|
</view>
|
|
93
123
|
</template>
|
|
94
124
|
</view>
|
|
@@ -97,141 +127,245 @@
|
|
|
97
127
|
|
|
98
128
|
<script lang="ts">
|
|
99
129
|
export default {
|
|
100
|
-
name:
|
|
130
|
+
name: "hy-upload",
|
|
101
131
|
options: {
|
|
102
132
|
addGlobalClass: true,
|
|
103
133
|
virtualHost: true,
|
|
104
|
-
styleIsolation:
|
|
134
|
+
styleIsolation: "shared",
|
|
105
135
|
},
|
|
106
|
-
}
|
|
136
|
+
};
|
|
107
137
|
</script>
|
|
108
138
|
|
|
109
139
|
<script setup lang="ts">
|
|
110
|
-
import { ref,
|
|
111
|
-
import
|
|
112
|
-
import type
|
|
113
|
-
import
|
|
114
|
-
import {
|
|
115
|
-
import { IconConfig } from '../../config'
|
|
140
|
+
import { ref, watch } from "vue";
|
|
141
|
+
import type { PropType, CSSProperties } from "vue";
|
|
142
|
+
import type { FileVo, IUploadEmits, ReadFunctionVo } from "./typing";
|
|
143
|
+
import { addUnit, bytesToSize, chooseFile, isArray } from "../../utils";
|
|
144
|
+
import { IconConfig } from "../../config";
|
|
116
145
|
// 组件
|
|
117
|
-
import HyIcon from
|
|
146
|
+
import HyIcon from "../hy-icon/hy-icon.vue";
|
|
118
147
|
|
|
119
148
|
/**
|
|
120
149
|
* 该组件用于上传图片或者视频等场景
|
|
121
150
|
* @displayName hy-upload
|
|
122
151
|
*/
|
|
123
|
-
defineOptions({})
|
|
152
|
+
defineOptions({});
|
|
124
153
|
|
|
125
|
-
const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
126
|
-
const {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
154
|
+
// const props = withDefaults(defineProps<IProps>(), defaultProps)
|
|
155
|
+
const props = defineProps({
|
|
156
|
+
/**
|
|
157
|
+
* 接受的文件类型
|
|
158
|
+
* @values all,media,image,file,video
|
|
159
|
+
* */
|
|
160
|
+
accept: {
|
|
161
|
+
type: String,
|
|
162
|
+
default: "image",
|
|
163
|
+
},
|
|
164
|
+
/** 根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。 */
|
|
165
|
+
extension: {
|
|
166
|
+
type: Array as PropType<string[]>,
|
|
167
|
+
default: () => [],
|
|
168
|
+
},
|
|
169
|
+
/** 图片或视频拾取模式,当accept为image类型时设置capture可选额外camera可以直接调起摄像头 */
|
|
170
|
+
capture: {
|
|
171
|
+
type: Array as PropType<("album" | "camera")[]>,
|
|
172
|
+
default: () => ["album", "camera"],
|
|
173
|
+
},
|
|
174
|
+
/** 当accept为video时生效,是否压缩视频 */
|
|
175
|
+
compressed: {
|
|
176
|
+
type: Boolean,
|
|
177
|
+
default: true,
|
|
178
|
+
},
|
|
179
|
+
/** 当accept为video时生效,可选值为back或front */
|
|
180
|
+
camera: {
|
|
181
|
+
type: String,
|
|
182
|
+
default: "back",
|
|
183
|
+
},
|
|
184
|
+
/** 当accept为video时生效,拍摄视频最长拍摄时间,单位秒 */
|
|
185
|
+
maxDuration: {
|
|
186
|
+
type: Number,
|
|
187
|
+
default: 60,
|
|
188
|
+
},
|
|
189
|
+
/** 上传区域的图标,只能内置图标 */
|
|
190
|
+
uploadIcon: {
|
|
191
|
+
type: String,
|
|
192
|
+
default: IconConfig.UPLOAD,
|
|
193
|
+
},
|
|
194
|
+
/** 上传区域的图标的字体颜色,只能内置图标 */
|
|
195
|
+
uploadIconColor: {
|
|
196
|
+
type: String,
|
|
197
|
+
default: "#D3D4D6",
|
|
198
|
+
},
|
|
199
|
+
/** 是否开启文件读取前事件 */
|
|
200
|
+
useBeforeRead: {
|
|
201
|
+
type: Boolean,
|
|
202
|
+
default: false,
|
|
203
|
+
},
|
|
204
|
+
/** 是否显示组件自带的图片预览功能 */
|
|
205
|
+
previewFullImage: {
|
|
206
|
+
type: Boolean,
|
|
207
|
+
default: true,
|
|
208
|
+
},
|
|
209
|
+
/** 最大上传数量 */
|
|
210
|
+
maxCount: {
|
|
211
|
+
type: Number,
|
|
212
|
+
default: 52,
|
|
213
|
+
},
|
|
214
|
+
/** 是否启用 */
|
|
215
|
+
disabled: {
|
|
216
|
+
type: Boolean,
|
|
217
|
+
default: false,
|
|
218
|
+
},
|
|
219
|
+
/**
|
|
220
|
+
* 预览上传的图片时的裁剪模式,和image组件mode属性一致
|
|
221
|
+
* @values scaleToFill,aspectFit,aspectFill,widthFix,heightFix,top,bottom,center,left,right,top left,top right,bottom left,bottom right
|
|
222
|
+
* */
|
|
223
|
+
imageMode: {
|
|
224
|
+
type: String,
|
|
225
|
+
default: "aspectFill",
|
|
226
|
+
},
|
|
227
|
+
/** 标识符,可以在回调函数的第二项参数中获取 */
|
|
228
|
+
name: {
|
|
229
|
+
type: String,
|
|
230
|
+
default: "",
|
|
231
|
+
},
|
|
232
|
+
/** 所选的图片的尺寸 */
|
|
233
|
+
sizeType: {
|
|
234
|
+
type: Array as PropType<("original" | "compressed")[]>,
|
|
235
|
+
default: ["original", "compressed"],
|
|
236
|
+
},
|
|
237
|
+
/** 是否开启图片多选,部分安卓机型不支持 */
|
|
238
|
+
multiple: {
|
|
239
|
+
type: Boolean,
|
|
240
|
+
default: false,
|
|
241
|
+
},
|
|
242
|
+
/** 是否展示删除按钮 */
|
|
243
|
+
deletable: {
|
|
244
|
+
type: Boolean,
|
|
245
|
+
default: true,
|
|
246
|
+
},
|
|
247
|
+
/** 文件大小限制,单位为byte */
|
|
248
|
+
maxSize: {
|
|
249
|
+
type: Number,
|
|
250
|
+
default: Number.MAX_VALUE,
|
|
251
|
+
},
|
|
252
|
+
/** 显示已上传的文件列表 */
|
|
253
|
+
fileList: {
|
|
254
|
+
type: Array as PropType<FileVo[]>,
|
|
255
|
+
default: () => [],
|
|
256
|
+
},
|
|
257
|
+
/** 上传区域的提示文字 */
|
|
258
|
+
uploadText: {
|
|
259
|
+
type: String,
|
|
260
|
+
default: "",
|
|
261
|
+
},
|
|
262
|
+
/** 内部预览图片区域和选择图片按钮的区域宽度 */
|
|
263
|
+
width: {
|
|
264
|
+
type: [String, Number],
|
|
265
|
+
default: 80,
|
|
266
|
+
},
|
|
267
|
+
/** 内部预览图片区域和选择图片按钮的区域高度 */
|
|
268
|
+
height: {
|
|
269
|
+
type: [String, Number],
|
|
270
|
+
default: 80,
|
|
271
|
+
},
|
|
272
|
+
/** 读取前的处理函数 */
|
|
273
|
+
beforeRead: Function as PropType<ReadFunctionVo>,
|
|
274
|
+
/** 读取后的处理函数 */
|
|
275
|
+
afterRead: Function as PropType<ReadFunctionVo>,
|
|
276
|
+
/** 定义需要用到的外部样式 */
|
|
277
|
+
customStyle: {
|
|
278
|
+
type: Object as PropType<CSSProperties>,
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
const emit = defineEmits<IUploadEmits>();
|
|
144
282
|
|
|
145
|
-
const lists = ref<FileVo[]>([])
|
|
146
|
-
|
|
147
|
-
const
|
|
283
|
+
const lists = ref<FileVo[]>([]);
|
|
284
|
+
// 上传按钮
|
|
285
|
+
const isInCount = ref<boolean>(true);
|
|
286
|
+
// 遮罩框
|
|
287
|
+
const previewImage = ref<boolean>(true);
|
|
148
288
|
|
|
149
289
|
const formatFileList = () => {
|
|
150
|
-
lists.value = fileList.
|
|
290
|
+
lists.value = props.fileList.map((item: FileVo) =>
|
|
151
291
|
Object.assign(Object.assign({}, item), {
|
|
152
292
|
// 如果item.url为本地选择的blob文件的话,无法判断其为video还是image,此处优先通过accept做判断处理
|
|
153
|
-
isImage: accept
|
|
154
|
-
isVideo: accept
|
|
155
|
-
deletable: item.deletable || deletable
|
|
293
|
+
isImage: props.accept === "image",
|
|
294
|
+
isVideo: props.accept === "video",
|
|
295
|
+
deletable: item.deletable || props.deletable,
|
|
156
296
|
}),
|
|
157
|
-
)
|
|
158
|
-
isInCount.value = lists.value.length < maxCount
|
|
159
|
-
}
|
|
297
|
+
);
|
|
298
|
+
isInCount.value = lists.value.length < props.maxCount;
|
|
299
|
+
};
|
|
160
300
|
|
|
161
301
|
watch(
|
|
162
|
-
() => fileList
|
|
302
|
+
() => props.fileList,
|
|
163
303
|
() => {
|
|
164
|
-
formatFileList()
|
|
304
|
+
formatFileList();
|
|
165
305
|
},
|
|
166
306
|
{ immediate: true, deep: true },
|
|
167
|
-
)
|
|
307
|
+
);
|
|
168
308
|
|
|
169
309
|
watch(
|
|
170
|
-
() => deletable
|
|
310
|
+
() => props.deletable,
|
|
171
311
|
() => {
|
|
172
|
-
formatFileList()
|
|
312
|
+
formatFileList();
|
|
173
313
|
},
|
|
174
|
-
)
|
|
314
|
+
);
|
|
175
315
|
|
|
176
316
|
watch(
|
|
177
|
-
() => maxCount
|
|
317
|
+
() => props.maxCount,
|
|
178
318
|
() => {
|
|
179
|
-
formatFileList()
|
|
319
|
+
formatFileList();
|
|
180
320
|
},
|
|
181
|
-
)
|
|
321
|
+
);
|
|
182
322
|
|
|
183
323
|
watch(
|
|
184
|
-
() => accept
|
|
324
|
+
() => props.accept,
|
|
185
325
|
() => {
|
|
186
|
-
formatFileList()
|
|
326
|
+
formatFileList();
|
|
187
327
|
},
|
|
188
|
-
)
|
|
328
|
+
);
|
|
189
329
|
|
|
190
330
|
const chooseFileFn = () => {
|
|
191
|
-
if (disabled
|
|
331
|
+
if (props.disabled) return;
|
|
192
332
|
// 如果用户传入的是字符串,需要格式化成数组
|
|
193
|
-
let capture
|
|
194
|
-
try {
|
|
195
|
-
capture = Array.isArray(capture) ? capture : capture!.split(',')
|
|
196
|
-
} catch (e) {
|
|
197
|
-
capture = []
|
|
198
|
-
}
|
|
199
333
|
chooseFile(
|
|
200
334
|
Object.assign(
|
|
201
335
|
{
|
|
202
|
-
accept: accept
|
|
203
|
-
extension: extension
|
|
204
|
-
multiple: multiple
|
|
205
|
-
capture: capture,
|
|
206
|
-
compressed: compressed
|
|
207
|
-
maxDuration: maxDuration
|
|
208
|
-
sizeType: sizeType
|
|
209
|
-
camera: camera
|
|
336
|
+
accept: props.accept,
|
|
337
|
+
extension: props.extension,
|
|
338
|
+
multiple: props.multiple,
|
|
339
|
+
capture: props.capture,
|
|
340
|
+
compressed: props.compressed,
|
|
341
|
+
maxDuration: props.maxDuration,
|
|
342
|
+
sizeType: props.sizeType,
|
|
343
|
+
camera: props.camera,
|
|
210
344
|
},
|
|
211
345
|
{
|
|
212
|
-
maxCount: maxCount
|
|
346
|
+
maxCount: props.maxCount - lists.value.length,
|
|
213
347
|
},
|
|
214
348
|
),
|
|
215
349
|
)
|
|
216
350
|
.then((res: any) => {
|
|
217
|
-
onBeforeRead(multiple
|
|
351
|
+
onBeforeRead(props.multiple ? res : res[0]);
|
|
218
352
|
})
|
|
219
353
|
.catch((error) => {
|
|
220
|
-
emit(
|
|
221
|
-
})
|
|
222
|
-
}
|
|
354
|
+
emit("error", error);
|
|
355
|
+
});
|
|
356
|
+
};
|
|
223
357
|
// 文件读取之前
|
|
224
358
|
const onBeforeRead = (file: FileVo) => {
|
|
225
|
-
let res: any = true
|
|
359
|
+
let res: any = true;
|
|
226
360
|
// beforeRead是否为一个方法
|
|
227
|
-
if (typeof props.beforeRead ===
|
|
361
|
+
if (typeof props.beforeRead === "function") {
|
|
228
362
|
// 如果用户定义了此方法,则去执行此方法,并传入读取的文件回调
|
|
229
|
-
res = props.beforeRead(file, getDetail())
|
|
363
|
+
res = props.beforeRead(file, getDetail());
|
|
230
364
|
}
|
|
231
|
-
if (useBeforeRead
|
|
365
|
+
if (props.useBeforeRead) {
|
|
232
366
|
res = new Promise((resolve, reject) => {
|
|
233
367
|
emit(
|
|
234
|
-
|
|
368
|
+
"beforeRead",
|
|
235
369
|
Object.assign(
|
|
236
370
|
Object.assign(
|
|
237
371
|
{
|
|
@@ -241,149 +375,150 @@ const onBeforeRead = (file: FileVo) => {
|
|
|
241
375
|
),
|
|
242
376
|
{
|
|
243
377
|
callback: (ok: any) => {
|
|
244
|
-
ok ? resolve(ok) : reject()
|
|
378
|
+
ok ? resolve(ok) : reject();
|
|
245
379
|
},
|
|
246
380
|
},
|
|
247
381
|
),
|
|
248
|
-
)
|
|
249
|
-
})
|
|
382
|
+
);
|
|
383
|
+
});
|
|
250
384
|
}
|
|
251
|
-
if (!res) return
|
|
252
|
-
if (typeof res ===
|
|
253
|
-
res.then((data: any) => onAfterRead(data || file))
|
|
385
|
+
if (!res) return;
|
|
386
|
+
if (typeof res === "function") {
|
|
387
|
+
res.then((data: any) => onAfterRead(data || file));
|
|
254
388
|
} else {
|
|
255
|
-
onAfterRead(file)
|
|
389
|
+
onAfterRead(file);
|
|
256
390
|
}
|
|
257
|
-
}
|
|
391
|
+
};
|
|
258
392
|
const getDetail = (index?: number) => {
|
|
259
393
|
return {
|
|
260
|
-
name: name
|
|
261
|
-
index: index == null ? fileList.
|
|
262
|
-
}
|
|
263
|
-
}
|
|
394
|
+
name: props.name,
|
|
395
|
+
index: index == null ? props.fileList.length : index,
|
|
396
|
+
};
|
|
397
|
+
};
|
|
264
398
|
const onAfterRead = (file: FileVo) => {
|
|
265
|
-
const oversize =
|
|
266
|
-
? file.some((item) => item.size > maxSize
|
|
267
|
-
: file.size > maxSize
|
|
399
|
+
const oversize = isArray(file)
|
|
400
|
+
? file.some((item) => item.size > props.maxSize)
|
|
401
|
+
: Number(file.size) > props.maxSize;
|
|
268
402
|
if (oversize) {
|
|
269
403
|
emit(
|
|
270
|
-
|
|
404
|
+
"oversize",
|
|
271
405
|
Object.assign(
|
|
272
406
|
{
|
|
273
407
|
file,
|
|
274
408
|
},
|
|
275
409
|
getDetail(),
|
|
276
410
|
),
|
|
277
|
-
)
|
|
278
|
-
return
|
|
411
|
+
);
|
|
412
|
+
return;
|
|
279
413
|
}
|
|
280
|
-
if (typeof props.afterRead ===
|
|
281
|
-
props.afterRead(file, getDetail())
|
|
414
|
+
if (typeof props.afterRead === "function") {
|
|
415
|
+
props.afterRead(file, getDetail());
|
|
282
416
|
}
|
|
283
417
|
emit(
|
|
284
|
-
|
|
418
|
+
"afterRead",
|
|
285
419
|
Object.assign(
|
|
286
420
|
{
|
|
287
421
|
file,
|
|
288
422
|
},
|
|
289
423
|
getDetail(),
|
|
290
424
|
),
|
|
291
|
-
)
|
|
292
|
-
}
|
|
425
|
+
);
|
|
426
|
+
};
|
|
293
427
|
|
|
294
428
|
/**
|
|
295
429
|
* @description 删除文件
|
|
296
430
|
* */
|
|
297
431
|
const deleteItem = (index: number) => {
|
|
298
|
-
fileList.
|
|
299
|
-
isInCount.value = lists.value.length < maxCount
|
|
432
|
+
props.fileList.splice(index, 1);
|
|
433
|
+
isInCount.value = lists.value.length < props.maxCount;
|
|
300
434
|
emit(
|
|
301
|
-
|
|
435
|
+
"delete",
|
|
302
436
|
Object.assign(Object.assign({}, getDetail(index)), {
|
|
303
|
-
file: fileList
|
|
437
|
+
file: props.fileList[index],
|
|
304
438
|
}),
|
|
305
|
-
)
|
|
306
|
-
}
|
|
439
|
+
);
|
|
440
|
+
};
|
|
307
441
|
|
|
308
442
|
/**
|
|
309
443
|
* @description 预览图片
|
|
310
444
|
* */
|
|
311
445
|
const onPreviewImage = (previewItem: FileVo, index: number) => {
|
|
312
|
-
if (!previewItem.isImage || !previewFullImage
|
|
313
|
-
let current = 0
|
|
314
|
-
const urls = []
|
|
315
|
-
let imageIndex = 0
|
|
316
|
-
for (
|
|
317
|
-
const item: FileVo = lists.value[i]
|
|
318
|
-
if (item.isImage || (item.type && item.type ===
|
|
319
|
-
urls.push(item.url || item.thumb)
|
|
446
|
+
if (!previewItem.isImage || !props.previewFullImage) return;
|
|
447
|
+
let current = 0;
|
|
448
|
+
const urls: string[] = [];
|
|
449
|
+
let imageIndex = 0;
|
|
450
|
+
for (let i = 0; i < lists.value.length; i++) {
|
|
451
|
+
const item: FileVo = lists.value[i];
|
|
452
|
+
if (item.isImage || (item.type && item.type === "image")) {
|
|
453
|
+
urls.push(item.url || (item.thumb as string));
|
|
320
454
|
if (i === index) {
|
|
321
|
-
current = imageIndex
|
|
455
|
+
current = imageIndex;
|
|
322
456
|
}
|
|
323
|
-
imageIndex += 1
|
|
457
|
+
imageIndex += 1;
|
|
324
458
|
}
|
|
325
459
|
}
|
|
326
|
-
if (urls.length < 1)
|
|
327
|
-
return
|
|
328
|
-
}
|
|
460
|
+
if (!urls || urls.length < 1) return;
|
|
329
461
|
uni.previewImage({
|
|
330
462
|
urls: urls,
|
|
331
463
|
current: current,
|
|
332
464
|
fail() {
|
|
333
|
-
uni.showToast({ title:
|
|
465
|
+
uni.showToast({ title: "预览图片失败" });
|
|
334
466
|
},
|
|
335
|
-
})
|
|
336
|
-
}
|
|
467
|
+
});
|
|
468
|
+
};
|
|
337
469
|
|
|
338
470
|
/**
|
|
339
471
|
* @description 预览视频
|
|
340
472
|
* */
|
|
341
473
|
const onPreviewVideo = (index: number) => {
|
|
342
|
-
if (!previewFullImage
|
|
343
|
-
let current = 0
|
|
344
|
-
const sources: any[] = []
|
|
345
|
-
let videoIndex = 0
|
|
474
|
+
if (!props.previewFullImage) return;
|
|
475
|
+
let current = 0;
|
|
476
|
+
const sources: any[] = [];
|
|
477
|
+
let videoIndex = 0;
|
|
346
478
|
for (let i = 0; i < lists.value.length; i++) {
|
|
347
|
-
const item: FileVo = lists.value[i]
|
|
348
|
-
if (item.isVideo || (item.type && item.type ===
|
|
479
|
+
const item: FileVo = lists.value[i];
|
|
480
|
+
if (item.isVideo || (item.type && item.type === "video")) {
|
|
349
481
|
sources.push(
|
|
350
482
|
Object.assign(Object.assign({}, item), {
|
|
351
|
-
type:
|
|
483
|
+
type: "video",
|
|
352
484
|
}),
|
|
353
|
-
)
|
|
485
|
+
);
|
|
354
486
|
if (i === index) {
|
|
355
|
-
current = videoIndex
|
|
487
|
+
current = videoIndex;
|
|
356
488
|
}
|
|
357
|
-
videoIndex += 1
|
|
489
|
+
videoIndex += 1;
|
|
358
490
|
}
|
|
359
491
|
}
|
|
360
492
|
if (sources.length < 1) {
|
|
361
|
-
return
|
|
493
|
+
return;
|
|
362
494
|
}
|
|
363
495
|
// #ifdef MP-WEIXIN
|
|
364
496
|
wx.previewMedia({
|
|
365
497
|
sources: sources,
|
|
366
498
|
current: current,
|
|
367
499
|
fail() {
|
|
368
|
-
uni.showToast({ title:
|
|
500
|
+
uni.showToast({ title: "预览视频失败" });
|
|
369
501
|
},
|
|
370
|
-
})
|
|
502
|
+
});
|
|
371
503
|
// #endif
|
|
372
|
-
}
|
|
504
|
+
};
|
|
373
505
|
|
|
374
506
|
const onClickPreview = (item: FileVo, index: number) => {
|
|
375
|
-
if (!previewFullImage
|
|
507
|
+
if (!props.previewFullImage) return;
|
|
376
508
|
switch (item.type) {
|
|
377
|
-
case
|
|
378
|
-
onPreviewVideo(index)
|
|
379
|
-
break
|
|
509
|
+
case "video":
|
|
510
|
+
onPreviewVideo(index);
|
|
511
|
+
break;
|
|
380
512
|
default:
|
|
381
|
-
break
|
|
513
|
+
break;
|
|
382
514
|
}
|
|
383
|
-
emit(
|
|
384
|
-
|
|
515
|
+
emit(
|
|
516
|
+
"clickPreview",
|
|
517
|
+
Object.assign(Object.assign({}, item), getDetail(index)),
|
|
518
|
+
);
|
|
519
|
+
};
|
|
385
520
|
</script>
|
|
386
521
|
|
|
387
522
|
<style lang="scss" scoped>
|
|
388
|
-
@import
|
|
523
|
+
@import "./index.scss";
|
|
389
524
|
</style>
|