使用vue+el-upload 实现图片上传,可浏览大图,可删除功能。
第一步
首先要搞定图片上传的接口和服务器,写在index.js里,通过export default{}抛出。
import Fetch from "./fetch";
import axios from "axios";
export default {
// 新上传图片
async uploadImage(file) {
return new Promise((resolve, reject) => {
let headers = {
"Content-Type": "multipart/form-data" //设置响应头
};
let data = new FormData();
data.append("filedata", file);
axios({
url: "/fdfs/imageupload", //要上传的地址
data: data,
method: "POST",
header: headers
})
.then(suc => {
if (suc.data) {
resolve(suc.data);
} else {
resolve(false);
}
})
.catch(err => {
reject(false);
});
});
},
};
第二步
从elementUI里准备选择一个喜欢的上传组件
<div>
<el-upload
action="#" //必选参数,上传的地址
ref="upload"
list-type="picture-card" //文件列表的类型( text/picture/picture-card)
:http-request="UploadImage" //覆盖默认的上传行为,可以自定义上传的实现(function)
:on-preview="handlePictureCardPreview" //点击文件列表中已上传的文件时的钩子
:on-remove="handleRemove" //文件列表移除文件时的钩子
:before-upload="beforeAvatarUpload" //上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。
:limit="2" //最大允许上传个数
:on-change="handleChange" //文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
:on-exceed="handleExceed" //文件超出个数限制时的钩子
:file-list="formData.fileList" //上传的文件列表, 例如: [{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}]
accept=".jpg,.jpeg,.png" //文件格式限制
>
<i class="el-icon-plus"></i>
</el-upload>
<!--下面是点击放大图片的弹窗-->
<el-dialog :visible.sync="dialogVisible" append-to-body>
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
第三步
开始写方法来实现功能,因为我写的是个添加编辑子组件,所以从父组件里拿了数据。
<script>
import interfaces from "@/interfaces/index"; //注意引入接口文件
export default {
components: {},
props: {
// 从父组件接收数据参数
editRuleForm:{
type: Object,
default (){
return null;
},
},
},
data() {
return {
dialogImageUrl: '', //这个是放大展示弹框里的图片
dialogVisible: false,
//用于给后端传参的字段
ruleForm:{
picturePath:[], //图片数组
},
//新图片数组
formData: {
fileList: [],//图片数组
},
};
},
methods: {
//获取父组件的数据参数editRuleForm
geteditRuleForm(){
this.ruleForm = this.editRuleForm
//判断接口里传回来的图片数组里有没有图片,有的话就赋值给formData.fileList[],这样图片回显功能就ok了。
if(this.ruleForm.picturePath.length > 0){
this.formData.fileList = this.ruleForm.picturePath.map(item => {
return{
url:item
}
})
}
},
//提交
submitForm() {
this.$refs['ruleForm'].validate(async (valid) => {
if (valid) {
//查找formData.fileList[]里的图片地址
let fileListArr = [];
this.formData.fileList.forEach(function(item,index,) {
fileListArr.push(item.url);
});
this.ruleForm.picturePath = fileListArr
//传回给父组件
this.$emit('benefitaddSubmit', this.ruleForm);
}
});
},
//取消
cancel() {
if (this.$refs["ruleForm"]) {
this.$refs["ruleForm"].resetFields();
this.$refs["ruleForm"].clearValidate();
}
this.$emit('benefitaddCancel', this.ruleForm);
},
//删除图片
handleRemove(file, fileList) {
// 判断是否是正确格式图片才能执行删除
if (file && file.status === "success") {
let Pics = this.formData.fileList;
//查找对比点击图片的url地址和formData.fileList[]里的url地址是否有对应的,一样的话就删除
Pics.forEach((item, index) => {
if (file.url == item.url) {
Pics.splice(index, 1);
}
});
}
},
//查看大图
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
//图片发生改变的时候触发
handleChange(file, fileList) {
console.log("handleChange-fileList",fileList);
console.log("handleChange-file",file);
},
//最重要的地方!!!上传!!!
async UploadImage(file) {
//搞清楚后端需要的参数
let res = await interfaces.uploadImage(file.file);
//将上传图片的uid和接口返回的地址存起来
let obj = {
uid: file.file.uid,
url: res,
};
this.formData.fileList.push(obj);
console.log("上传formData.fileList:",this.formData.fileList);
},
// 上传检测
beforeAvatarUpload(file) {
//限制图片上传的格式
const types = ["image/jpg", "image/png","image/jpeg"];
const isImage = types.includes(file.type);
//限制图片上传的大小
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isImage) {
this.$message.error("上传图片只能是 JPG、JPEG、PNG 格式!");
// this.$refs.upload.handleRemove(file);
}
if (!isLt2M) {
this.$message.error("上传图片大小不能超过 2MB!");
// this.$refs.upload.handleRemove(file);
}
return isImage && isLt2M;
},
//控制上传数量提示
handleExceed(files, fileList) {
this.$message.warning(`最多上传2个文件`);
},
},
created() {
this.geteditRuleForm()
console.log("editRuleForm:",this.editRuleForm)
},
};
</script>
然后就OK啦,下面是效果。
图片排列的样式使用了 display: flex;