# upload组件封装
<template>
<div>
<el-upload v-model:file-list="fileList" :accept="props.accept" action="#" list-type="picture-card"
:auto-upload="true" :limit="props.numLimit" :http-request="uploadpromise">
<template #file="{ file }">
<div class="upload">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<span class="upload-delete" @click="handleRemove(file)">
删除
</span>
</span>
</div>
</template>
<div class="imgtip">
<div class="addiccon">+</div>
<div class="title">上传照片</div>
</div>
</el-upload>
</div>
</template>
<script setup>
import { defineEmits, ref, defineProps, watch } from "vue"
import { ElMessage } from 'element-plus'
const fileList = ref([])
const props = defineProps({
accept: {
type: String,
default: "image/jpeg,image/png,image/gif,image/jpg,image/bmp"
},
sizeLimit: {
type: [String, Number],
default: 8
},
numLimit: {
type: [String, Number],
default: 1
},
width: {
type: [String, Number],
default: '104px',
validator(value) {
return (!isNaN(parseFloat(value)) && isFinite(value)) || ['px', 'em', 'rem', 'vw'].some(item => {
return value.indexOf(item) > -1
})
}
},
height: {
type: [String, Number],
default: '104px',
validator(value) {
return (!isNaN(parseFloat(value)) && isFinite(value)) || ['px', 'em', 'rem', 'vh'].some(item => {
return value.indexOf(item) > -1
})
}
}
})
const style = {
width: !isNaN(parseFloat(props.width)) && isFinite(props.width) ? props.width + 'px' : props.width,
height: !isNaN(parseFloat(props.height)) && isFinite(props.height) ? props.height + 'px' : props.height
}
const emit = defineEmits(['uploaded'])
watch(fileList, (newValue) => {
emit('uploaded', newValue)
})
const listLimit = (file) => {
const typeLimitBool = props.accept.split(',').some(_type => file.type === _type);
if (!typeLimitBool) {
ElMessage.error('请上传格式正确的图片');
}
const sizeLimitBool = file.size / 1024 / 1024 < props.sizeLimit;
if (!sizeLimitBool) {
ElMessage.error(`请使用小于${props.sizeLimit}MB的图片!`);
}
let result = sizeLimitBool && typeLimitBool;
return result
}
const uploadpromise = (param) => {
const file = param.file
return new Promise((resolve, reject) => {
if (listLimit(file)) { resolve(true) } else {
reject(new Error('格式不正确'));
}
})
}
const handleRemove = (file) => {
const fileID = file.uid
// 从数组中,找到图片对应的索引值
const i = fileList.value.findIndex(x => x.uid === fileID)
// 调用splice方法,移除图片信息
fileList.value.splice(i, 1)
emit('uploaded', fileList.value)
}
</script>
<style lang="less" scoped>
:deep(.el-upload-list__item-thumbnail),
:deep(.el-upload-list__item),
:deep(.el-upload--picture-card) {
width: v-bind("style.width");
height: v-bind("style.width");
}
.imgtip {
.addiccon {
margin-left: 10px;
color: rgba(0, 0, 0, 0.65);
font-size: 50px;
// overflow: hidden;
}
.title {
font-size: 14px;
color: rgba(0, 0, 0, 0.65);
text-align: center;
line-height: 22px;
}
}
</style>
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
50
51
52
53
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
94
95
96
97
98
99
100
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
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
50
51
52
53
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
94
95
96
97
98
99
100
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