使用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;