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.照片墙效果

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

相关推荐
腾讯TNTWeb前端团队35 分钟前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪4 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试