现有的组件库无法满足手动上传文件到服务器,并支持通过按钮修改和移除文件的操作。所以我利用原生input进行封装,如有需要请拿走
1.页面部分
<div class="container">
<div class="upload-picture">
<template v-if="imageList.length > 0">
<div class="uploadItem" v-for="(item, index) in imageList" :key="index" style="margin: 0 10px 10px 0">
<img class="avatar" :src="item" alt="" srcset="" @click="updatePicture(index)" />
<div>
<el-button class="button1" type="default" size="mini" @click="updatePicture(index)">修改</el-button>
<el-button class="button1" type="default" size="mini" @click="remove(index)">移除</el-button>
</div>
</div>
</template>
<div class="uploadItem">
<input type="file" v-if="clearInputShow" hidden ref="uploadfile" @change="onChangeFile" />
<i class="el-icon-plus avatar-uploader-icon" @click="selectPicture"></i>
<el-button class="button" type="default" size="mini" @click="selectPicture">选择图片</el-button>
</div>
</div>
</div>
2、逻辑部分
export default {
props: {
imageList: {
type: Array,
default: () => []
},
},
data() {
return {
pictureIndex: "",
clearInputShow: true,
}
},
methods: {
// 上传
selectPicture() {
this.$refs.uploadfile.click();
},
// 修改
updatePicture(index) {
this.pictureIndex = index
this.$refs.uploadfile.click();
},
// 移除文件
remove(index) {
this.$emit("update:imageList", this.imageList.filter((item, i) => i != index))
},
// 手动上传文件
onChangeFile() {
// file上传的文件
let file = this.$refs.uploadfile.files[0];
const formData = new FormData()
// 上传文件的参数都以这种方法
formData.append('file', file)
formaData.append('fileName', file.name)
this.clearInputShow = false;
// 上传接口
this.$axios.post('接口地址', formData).then(res => {
this.clearInputShow = true;
// 假设res.data.picUrl是接口返回图片路径
// 没有下标,说明是新增,有下标是修改
if (this.pictureIndex === "") {
this.$emit("update:imageList", [...this.imageList, res.data.picUrl])
this.pictureIndex = ""
} else {
this.imageList.splice(this.pictureIndex, 1, res.data.picUrl)
this.$emit("update:imageList", [...this.imageList])
this.pictureIndex = ""
}
}).catch((error)=>{
this.clearInputShow = true;
})
},
}
}
3、样式部分
<style lang="less" scoped>
.upload-picture {
display: flex;
flex-wrap: wrap;
}
.uploadItem {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 178px;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
border: 1px dashed #d9d9d9;
margin-top: -10px;
}
.button {
width: 80px;
margin-top: 10px;
}
.button1 {
width: 60px;
margin-top: 10px;
}
.avatar {
width: 178px;
height: 178px;
display: block;
border: 1px dashed #d9d9d9;
}
</style>