Skip to content

Commit 09af44a

Browse files
committed
重新封装上传组件
1 parent adeefba commit 09af44a

File tree

9 files changed

+1183
-1206
lines changed

9 files changed

+1183
-1206
lines changed

.idea/misc.xml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/MainPhotoUpload.vue

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
<template>
2+
<div>
3+
<el-upload class="avatar-uploader" :action="action" :headers="headers" :data="data" :show-file-list="false"
4+
:on-success="handleUploadSuccess"
5+
:on-error="handleUploadError" :before-upload="handleBeforeUpload">
6+
<div v-if="url" @click.stop="handleRemove" class="cover">
7+
<i class="el-icon-delete avatar-uploader-icon"></i>
8+
</div>
9+
<img v-if="url" :src="url" class="avatar">
10+
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
11+
</el-upload>
12+
</div>
13+
</template>
14+
15+
<script>
16+
// 支持双向数据绑定,采用:url.sync
17+
// 支持$emit事件success,处理复杂上传成功回调函数
18+
19+
import {Upload} from '@/api/index';
20+
21+
export default {
22+
name: "MainPhotoUpload",
23+
// 组件外部数据
24+
props: {
25+
url: {
26+
type: String,
27+
},
28+
lgImg: {
29+
type: String,
30+
},
31+
action: {
32+
type: String,
33+
required: true
34+
},
35+
data: {
36+
type: Object,
37+
},
38+
},
39+
// 组件内部数据
40+
data() {
41+
return {
42+
headers: {
43+
Authorization: `Bearer ${sessionStorage.token}`
44+
},
45+
}
46+
},
47+
methods: {
48+
// 上传图片之前的检查
49+
handleBeforeUpload(file) {
50+
let reg = /^image\/(jpe?g|png)$/;
51+
const isImg = reg.test(file.type);
52+
const isLt2M = file.size / 1024 / 1024 < 2;
53+
if (!isImg) {
54+
this.$message.error('上传头像图片只能是 JPG/PNG 格式!');
55+
}
56+
if (!isLt2M) {
57+
this.$message.error('上传头像图片大小不能超过 2MB!');
58+
}
59+
return isImg && isLt2M;
60+
},
61+
// 删除图片
62+
async handleRemove() {
63+
// 删除图片
64+
let {status: statusMd} = await Upload.remove({src: this.url});
65+
let {status: statusLg} = await Upload.remove({src: this.lgImg});
66+
if (statusMd && statusLg) {
67+
this.$message.success('删除成功!');
68+
this.$emit("update:url", "");
69+
this.$emit("update:lgImg", "");
70+
}
71+
},
72+
// 上传图片成功
73+
handleUploadSuccess(res, file) {
74+
let {status, mdImg, lgImg} = res;
75+
this.$message.success('上传成功!');
76+
// 触发外部绑定的事件
77+
this.$emit('success', res);
78+
// 双向数据绑定触发
79+
this.$emit('update:url', mdImg);
80+
this.$emit("update:lgImg", lgImg);
81+
},
82+
// 上传图片失败
83+
handleUploadError({status, message}, file, fileList) {
84+
let {msg} = JSON.parse(message);
85+
switch (status) {
86+
case 401:
87+
this.$message.error(`错误:401,Token失效,请重新登录!`);
88+
break;
89+
case 400:
90+
this.$message.error(`错误:400,${msg}`);
91+
break;
92+
default:
93+
this.$message.error(`错误:${status},${msg}!`);
94+
break;
95+
}
96+
},
97+
}
98+
};
99+
</script>
100+
101+
<style scoped lang="less">
102+
.avatar-uploader .el-upload {
103+
border: 1px dashed #d9d9d9;
104+
border-radius: 6px;
105+
cursor: pointer;
106+
position: relative;
107+
overflow: hidden;
108+
109+
&:hover {
110+
border-color: #409EFF;
111+
}
112+
113+
.avatar-uploader-icon {
114+
font-size: 28px;
115+
color: #8c939d;
116+
width: 150px;
117+
height: 150px;
118+
line-height: 150px;
119+
text-align: center;
120+
}
121+
122+
.cover {
123+
content: "";
124+
display: block;
125+
position: absolute;
126+
left: 0;
127+
top: 0;
128+
width: 100%;
129+
height: 100%;
130+
z-index: 2;
131+
background-color: rgba(0, 0, 0, 0.7);
132+
opacity: 0;
133+
transition: all 0.5s;
134+
135+
.el-icon-delete {
136+
font-size: 18px;
137+
color: white;
138+
}
139+
}
140+
141+
&:hover .cover {
142+
opacity: 1;
143+
}
144+
145+
.avatar {
146+
width: 150px;
147+
height: 150px;
148+
display: block;
149+
}
150+
}
151+
</style>

src/components/SingleUpload.vue

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
2-
<el-upload class="avatar-uploader" :action="action" :headers="headers" :data="data" :show-file-list="false" :on-success="uploadSuccess"
3-
:on-error="uploadError" :before-upload="beforeUpload">
4-
<div v-if="url" @click.stop="removeImage" class="cover">
2+
<el-upload class="avatar-uploader" :action="action" :headers="headers" :data="data" :show-file-list="false" :on-success="handleUploadSuccess"
3+
:on-error="handleUploadError" :before-upload="handleBeforeUpload">
4+
<div v-if="url" @click.stop="handleRemove" class="cover">
55
<i class="el-icon-delete avatar-uploader-icon"></i>
66
</div>
77
<img v-if="url" :src="url" class="avatar">
@@ -40,7 +40,7 @@
4040
},
4141
methods: {
4242
// 上传图片之前的检查
43-
beforeUpload(file) {
43+
handleBeforeUpload(file) {
4444
let reg = /^image\/(jpe?g|png)$/;
4545
const isImg = reg.test(file.type);
4646
const isLt2M = file.size / 1024 / 1024 < 2;
@@ -53,29 +53,29 @@
5353
return isImg && isLt2M;
5454
},
5555
// 上传图片成功
56-
uploadSuccess(res, file) {
56+
handleUploadSuccess(res, file) {
5757
// 触发外部绑定的事件
5858
this.$emit('success', res);
5959
// 双向数据绑定触发
6060
this.$emit('update:url', res.src);
6161
},
62-
// 上传图片失败
63-
uploadError({ status, message }, file, fileList) {
64-
switch (status) {
65-
case 401:
66-
this.$message.error(`错误:401,Token失效,请重新登录!`);
67-
break;
68-
case 400:
69-
message = JSON.parse(message);
70-
this.$message.error(`错误:400,${message.msg}`);
71-
break;
72-
default:
73-
this.$message.error(`错误:${status},${message}!`);
74-
break;
75-
}
76-
},
62+
// 上传图片失败
63+
handleUploadError({status, message}, file, fileList) {
64+
let {msg} = JSON.parse(message);
65+
switch (status) {
66+
case 401:
67+
this.$message.error(`错误:401,Token失效,请重新登录!`);
68+
break;
69+
case 400:
70+
this.$message.error(`错误:400,${msg}`);
71+
break;
72+
default:
73+
this.$message.error(`错误:${status},${msg}!`);
74+
break;
75+
}
76+
},
7777
// 删除现有图片
78-
async removeImage() {
78+
async handleRemove() {
7979
// 如果不是默认头像,物理删除图片
8080
if (this.url != this.defaultImage) {
8181
let { status } = await Upload.remove({ src: this.url });

src/components/SliderUpload.vue

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<template>
2+
<div>
3+
<el-upload :file-list="fileList" :action="action" :headers="headers" :limit="6" list-type="picture-card"
4+
:before-upload="handleBeforeUpload"
5+
:on-success="handleSliderSuccess" :on-exceed="handleSliderExceed"
6+
:before-remove="handleSliderBeforeRemove"
7+
:on-error="handleUploadError" :on-preview="handleCardPreview">
8+
<i class="el-icon-plus"></i>
9+
</el-upload>
10+
<!-- 图片预览 -->
11+
<el-dialog width="30%" :visible.sync="dialogVisible">
12+
<img width="100%" :src="dialogImageUrl" alt/>
13+
</el-dialog>
14+
</div>
15+
</template>
16+
17+
<script>
18+
import {Upload} from '@/api/index';
19+
20+
export default {
21+
name: "SliderUpload",
22+
// 组件外部数据
23+
props: {
24+
value: {
25+
type: String,
26+
},
27+
action: {
28+
type: String,
29+
required: true
30+
},
31+
fileList:{
32+
type: Array,
33+
}
34+
},
35+
// 组件内部数据
36+
data() {
37+
return {
38+
dialogImageUrl: "",
39+
dialogVisible: false,
40+
headers: {
41+
Authorization: `Bearer ${sessionStorage.token}`
42+
},
43+
}
44+
},
45+
methods: {
46+
// 上传图片失败
47+
handleUploadError({status, message}, file, fileList) {
48+
let {msg} = JSON.parse(message);
49+
switch (status) {
50+
case 401:
51+
this.$message.error(`错误:401,Token失效,请重新登录!`);
52+
break;
53+
case 400:
54+
this.$message.error(`错误:400,${msg}`);
55+
break;
56+
default:
57+
this.$message.error(`错误:${status},${msg}!`);
58+
break;
59+
}
60+
},
61+
//上传之前的检查
62+
handleBeforeUpload(file) {
63+
const isImg = /^image\/(jpe?g|png)$/.test(file.type);
64+
const isLt2M = file.size / 1024 / 1024 < 2;
65+
if (!isImg) {
66+
this.$message.error("上传头像图片只能是 JPG/PNG 格式!");
67+
}
68+
if (!isLt2M) {
69+
this.$message.error("上传头像图片大小不能超过 2MB!");
70+
}
71+
return isImg && isLt2M;
72+
},
73+
//预览
74+
handleCardPreview(file) {
75+
this.dialogImageUrl = file.url;
76+
this.dialogVisible = true;
77+
},
78+
//上传文件成功
79+
handleSliderSuccess(response, file, fileList) {
80+
if (response.status) {
81+
let data = this.convertFileList(fileList);
82+
this.$emit("input", data);
83+
}
84+
},
85+
//超出限制
86+
handleSliderExceed(files, fileList) {
87+
this.$message.warning(`当前限制选择 6 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
88+
},
89+
//删除图片
90+
async handleSliderBeforeRemove(file, fileList) {
91+
let src = file.response.src;
92+
let {status} = await Upload.remove({src});
93+
if (status) {
94+
let i = fileList.findIndex(item => item.url == src);
95+
let copy = [...fileList];
96+
copy.splice(i, 1);
97+
let data = this.convertFileList(copy);
98+
this.$emit("input", data);
99+
return true;
100+
} else {
101+
return false;
102+
}
103+
},
104+
//转换数据格式
105+
convertFileList(fileList) {
106+
let res = [];
107+
fileList.forEach(function (item, index) {
108+
res.push(item.response.src);
109+
});
110+
return res.toString();
111+
},
112+
}
113+
}
114+
</script>
115+
116+
<style scoped>
117+
118+
</style>

0 commit comments

Comments
 (0)