el-upload照片墙自定义上传多张图片(手动一次性上传多张图片)包含图片回显,删除

需求:el-upload照片墙自定义上传多张图片(手动一次性上传多张图片)包含图片回显,删除,预览,在网上看了很多,都没有说怎么把数据转为file格式的,找了很久最终实现,

难点:怎么把接口获取到的图片转为file格式,如果不是file格式的话,那么后端无法识别,并且还要携带额外的参数

1.调用接口获取已上传图片,格式如下

获取到数据后,进行回显(调用接口我就不写了,我只写数据获取到后转为file格式)

fileImgList:用于照片回显

process.env.VUE_APP_SERVE:这个是全局的,公司地址,比如https://xx.cn,如果图片显示不出来,可以问后端要不要拼接其他,可以在浏览器测试

以下这俩个方法,直接复制,把参数对好就能转为file,格式是FILE

imageToBase64:图片转base64

base64ToFile:base64转File

that.formInline.files:用于存储file格式图片

javascript 复制代码
  query() {
            if (files.length > 0) {
                files.forEach((item) => {
                    this.fileImgList.push({
                        url: process.env.VUE_APP_SERVE + '/files' + item.path,
                        name: item.originalname
                    });
                    var image = new Image();
                    image.crossOrigin = '';
                    image.src = process.env.VUE_APP_SERVE + '/files' + item.path; // 'https://xx.cn' + item
                    const that = this;
                    image.onload = function () {
                        const base64 = that.imageToBase64(image); // 图片转base64
                        const file = that.base64ToFile(base64, item.path); // base64转File
                        that.formInline.files.push(file);
                    };
                });
            }
        },
        imageToBase64(img) {
            var canvas = document.createElement('canvas');
            canvas.width = img.width;
            canvas.height = img.height;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0, img.width, img.height);
            var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
            var dataURL = canvas.toDataURL('image/jpeg' + ext);
            return dataURL;
        },
        base64ToFile(urlData, fileName) {
            const arr = urlData.split(',');
            const mime = arr[0].match(/:(.*?);/)[1];
            const bytes = atob(arr[1]); // 解码base64
            let n = bytes.length;
            const ia = new Uint8Array(n);
            while (n--) {
                ia[n] = bytes.charCodeAt(n);
            }
            return new File([ia], fileName, { type: mime });
        }

2.删除已上传图片

直接复制,这个是删除FILE,FILE的图片

javascript 复制代码
 handleRemove(file) {
            // 从列表中删除当前的图片
            var that = this;
            try {
                var delname = file.url.split('/');
                that.formInline.files = that.formInline.files.filter((ele) => {
                    var name = ele.name.split('/');
                    return name[name.length - 1] !== delname[delname.length - 1];
                });
                console.log(that.formInline.files);
            } catch (error) {}
        }

3.上传图片

上传图片的change事件,每次上传成功把file.raw给files,注意!!file.raw就是后端需要的file格式的图片

javascript 复制代码
    OnChange(file, fileList) {
      const isType = file.type === "image/jpeg" || "image/png";
      const isLt5M = file.size / 1024 / 1024 < 5;
      if (!isType) {
        this.$message.error("上传图片只能是 JPG 格式!");
        fileList.pop();
      }
      if (!isLt5M) {
        this.$message.error("上传图片大小不能超过 5MB!");
        fileList.pop();
      }
      this.formInline.files.push(file.raw);
    },

4.上传多张图片并且携带额外参数

注意!!这边如果要传数组,需要先转换为json格式再发给后端

javascript 复制代码
        async setCompanySubmit() {
            let formData = new FormData(); //  用FormData存放上传文件
            this.formInline.files.forEach((file, index) => {
                formData.append('files', file);
            });
            let { name, tel, truename, id } = this.formInline;
            formData.append('name', name);
            formData.append('tel', tel);
            formData.append('truename', truename);
            formData.append('id', id);
            const res = await Api_setCompany(formData);
            if (res.code == 200) {
                this.$message.success('成功!!!');
                this.unitDialogVisible = false;
                this.fileImgList = [];
                this.$refs.uploadCompanyRef.clearFiles();
            }
        }

上传参数如下,有多个files文件

5.完整代码(仅作参考,需要根据实际情况修改)

javascript 复制代码
<template>
    <div>
        <el-upload
            action="#"
            list-type="picture-card"
            multiple
            :on-remove="handleRemove"
            :on-change="OnChange"
            :file-list="fileImgList"
            :auto-upload="false"
            ref="uploadCompanyRef"
        >
            <i class="el-icon-plus"></i>
            <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,最多上传5张且单张图片不超过5M</div>
        </el-upload>
        <el-button type="primary" size="default" @click="setCompanySubmit()">上传</el-button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            fileImgList: [],
            formInline: {
                files: [],
                name: '',
                id: 0
            }
        };
    },
    mounted() {
        this.query();
    },
    methods: {
        query() {
            if (files.length > 0) {
                files.forEach((item) => {
                    this.fileImgList.push({
                        url: process.env.VUE_APP_SERVE + '/files' + item.path,
                        name: item.originalname
                    });
                    var image = new Image();
                    image.crossOrigin = '';
                    image.src = process.env.VUE_APP_SERVE + '/files' + item.path; // 'https://xx.cn' + item
                    const that = this;
                    image.onload = function () {
                        const base64 = that.imageToBase64(image); // 图片转base64
                        const file = that.base64ToFile(base64, item.path); // base64转File
                        that.formInline.files.push(file);
                    };
                });
            }
        },
        imageToBase64(img) {
            var canvas = document.createElement('canvas');
            canvas.width = img.width;
            canvas.height = img.height;
            var ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0, img.width, img.height);
            var ext = img.src.substring(img.src.lastIndexOf('.') + 1).toLowerCase();
            var dataURL = canvas.toDataURL('image/jpeg' + ext);
            return dataURL;
        },
        base64ToFile(urlData, fileName) {
            const arr = urlData.split(',');
            const mime = arr[0].match(/:(.*?);/)[1];
            const bytes = atob(arr[1]); // 解码base64
            let n = bytes.length;
            const ia = new Uint8Array(n);
            while (n--) {
                ia[n] = bytes.charCodeAt(n);
            }
            return new File([ia], fileName, { type: mime });
        },
        handleRemove(file) {
            // 从列表中删除当前的图片
            var that = this;
            try {
                var delname = file.url.split('/');
                that.formInline.files = that.formInline.files.filter((ele) => {
                    var name = ele.name.split('/');
                    return name[name.length - 1] !== delname[delname.length - 1];
                });
                console.log(that.formInline.files);
            } catch (error) {}
        },
        OnChange(file, fileList) {
            console.log(file, fileList, '多选情况下传参');
            const isType = file.type === 'image/jpeg' || 'image/png';
            const isLt5M = file.size / 1024 / 1024 < 5;
            if (!isType) {
                this.$message.error('上传图片只能是 JPG 格式!');
                fileList.pop();
            }
            if (!isLt5M) {
                this.$message.error('上传图片大小不能超过 5MB!');
                fileList.pop();
            }
            this.formInline.files.push(file.raw);
        },
        async setCompanySubmit() {
            let formData = new FormData(); //  用FormData存放上传文件
            this.formInline.files.forEach((file, index) => {
                formData.append('files', file);
            });
            let { name, tel, truename, id } = this.formInline;
            formData.append('name', name);
            formData.append('tel', tel);
            formData.append('truename', truename);
            formData.append('id', id);
            const res = await Api_setCompany(formData);
            if (res.code == 200) {
                this.$message.success('成功!!!');
                this.unitDialogVisible = false;
                this.fileImgList = [];
                this.$refs.uploadCompanyRef.clearFiles();
            }
        }
    }
};
</script>

<style lang="scss" scoped></style>

6.照片墙效果

文章到此结束,希望对你有所帮助~

相关推荐
李纲明3 分钟前
微信小程序 getSystemInfo 提示已废弃、屏幕高度算错胶囊还对不齐?getWindowInfo 和 getDeviceInfo 怎么接才稳
javascript·微信小程序·小程序·小程序开发·devdiy
deli00722 分钟前
从一句反馈到一次升级:Mystudy 的自进化实践
前端
Felven1 小时前
C. Brr Brrr Patapim
c语言·开发语言
FungLeo1 小时前
成为全栈·Vue 管理后台篇·用 fetch 建一层可控的请求内核
前端·javascript·vue.js·http·fetch·formdata·接口封装
用户84298142418101 小时前
ByteJS,让重要的 JavaScript 以字节码运行。
javascript
路溪非溪2 小时前
python标准库使用总结
开发语言·python
FungLeo3 小时前
成为全栈·Vue 管理后台篇·Vue Router如何守住多角色后台边界
前端·javascript·vue.js·rbac·vue router·路由守卫·前端权限
FungLeo3 小时前
成为全栈·Vue 管理后台篇·分页只显示第一页:从接口total 定位到前端修复
前端·vue.js·状态模式·分页·naive ui·服务端分页·前端问题排查
ZhengEnCi3 小时前
苹果滑动为什么有「肉感」:橡皮筋越界阻尼与弹簧动画的物理原理
前端
Moment3 小时前
不会后期的我,发现了一个开源胶片神器😍😍😍
前端·后端·开源