当前位置:   article > 正文

vue+Springboot实现头像预览及上传_element-plus 头像上传 前后端代码

element-plus 头像上传 前后端代码


请注意,项目使用vue3 + Element-Plus 2.3.7 + springboot 2.7.8!

思路说明

element-plus提供了el-upload组件实现头像上传,具体的属性说明请参考官方文档
组件拿到用户上传的图片之后,首先需要展示,用户确认后再传输给后端,后端接收图片资源后进行保存,并将保存状态返回给前端。

代码实现

前端代码

  • 前端代码-template
<el-dialog class="avatarDialog" :showClose="false" center v-model="avatarDialogVisible" title="更新头像">
      <el-upload ref="upload" class="avatar-uploader" :before-upload="beforeAvatarUpload" action="#"
               :http-request="uploadFile" :auto-upload="false" multiple list-type="picture-card" :file-list="fileList"
               :on-change="fileChange">
           <el-icon>
               <Plus />
           </el-icon>
           <template #file="{ file }">
               <img :src="file.url" alt="" />
           </template>
       </el-upload>
       <template #footer>
           <span class="dialog-footer">
               <el-button type="primary" @click="handleUpdateAvatar">
                   确认更新
               </el-button>
               <el-button @click="cancel">取消</el-button>
           </span>
       </template>
 </el-dialog>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

这里对用到的属性进行简单解释:

1、before-upload:是el-upload组件提供的钩子函数,在图片上传之前执行,一般用于检查图片的格式和大小是否满足条件
2、action属性:图片上传到后端的路径,我这里不使用该属性,用“#”占位(你可以用其它字符串),后面使用自定义的上传方法。这里有个小坑,使用该属性会出现跨域问题
3、http-request:自定义的上传方法,会覆盖默认的xhr上传行为,如果需要使用它,你得关闭自动上传,即auto-upload=“false”
4、list-type:选中文件后以什么样的形式展示,可选值有:text、picture、picture-card
5、file-list:一般和data中的数据绑定,表示上传的文件列表
6、multiple:是否支持多选文件
7、on-change:文件状态改变时的钩子函数,在添加文件、上传成功和上传失败都会执行该函数

然后使用插槽,对图片选中后进行展示,也就是代码中间的template部分

  • 前端代码-data部分
data() {
        return {
            fileList: [],              //上传的文件列表
            avatarDialogVisible: false,   //头像框显示控制
        }
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 前端代码-methods部分
methods: {
        // 自定义上传图片方法,参数必须为params
        uploadFile(params) {
            const file = params.file;
            var forms = new FormData();
            // 我这里需要将更新时间和uid同时传给后端,后端使用对象接收,所以没有设置content-type
            // 如果你只传file,要设置axios中headers的content-type为:multipart/form-data
            forms.append("file", file);
            forms.append("updatedTime", this.$utils.getNowFormatTime());
            forms.append("uid", this.user.uid);
            this.$axios({
                method: "post",
                url: "/avatar/upload",
                data: forms,
            }).then(res => {
                if (res.data.code == "200") {
                    this.$message({
                        message: '上传成功',
                        type: 'success'
                    })
                    this.avatarDialogVisible = false;
                } else {
                    this.$message({
                        message: '上传失败',
                        type: 'error'
                    })
                }
            }).catch(err => {
                console.log("上传文件时发生错误: " + err);
            })
        },
        // 上传图片时检查
        beforeAvatarUpload(file) {
            //允许的图片类型
            const imgType = (file.type === 'image/jpeg') || (file.type === 'image/png') || (file.type === 'image/gif');
            //文件大小3M
            const imgLimit= (file.size / 1024 / 1024) < 3;
            if (!imgType) {
                this.$message.error("只允许jpg、png、gif格式的图片");
                return false;
            }
            if (!imgLimit) {
                this.$message.error("上传的图片大小不能超过3MB");
                return false;
            }
            console.log("检查通过");
            return true;
        },
        //文件改变时的钩子函数,只能上传一张,选中后会覆盖掉之前的图片,
        fileChange(file, fileList) {
        	//this.file表示上一张被选中的图片,file.raw表示当前选中的图片
            this.file = file.raw;
            if (fileList.length > 0) {
                this.fileList = [fileList[fileList.length - 1]];
            }
        },
        // 确认修改头像
        handleUpdateAvatar() {
            this.$refs['upload'].submit();
            this.avatarDialogVisible = false;
            this.$refs['upload'].clearFiles();
        },
        // 取消上传头像
        cancel() {
            this.avatarDialogVisible = false;
            this.$refs['upload'].clearFiles();
        },
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

后端代码

  • 实体类Upload-接收前端参数
@Data
public class Upload {
    private MultipartFile file;
    private String uid;
    private String updatedTime;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • controller层
@PostMapping("/upload")
public Result avatar(Upload upload) throws FileNotFoundException {
    MultipartFile avatarFile = upload.getFile();
    String uid = upload.getUid();
    String updatedTime = upload.getUpdatedTime();
    if(avatarFile.isEmpty()){
        return Result.fail("文件上传失败");
    }

    // 设置文件名:uid+原文件名
    String fileName = uid + "_" + avatarFile.getOriginalFilename();
    //获取静态资源目录所在的位置路径:/项目名称/target/classes
    //注意,如果你的项目要部署到云服务器,这个方法会失效
    String path = ResourceUtils.getURL("classpath:").getPath();
    //拼接保存头像的目录路径
    File avatarDir = new File(path + "/static/upload/avatar");
    //如果文件路径不存在,就新建一个,使用mkdirs()函数,可以创建多级目录
    if(!avatarDir.exists()){
        System.out.println("正在创建/upload/avatar目录");
        avatarDir.mkdirs();
    }

    //文件保存的路径,这里的System.getProperty("file.separator")表示当前系统下的分隔符,如:"/"
    File dest = new File(avatarDir + System.getProperty("file.separator") + fileName);
    //存储在数据库中的路径
    String storePath = "/static/upload/avatar/" + fileName;

    try{
        //保存图片,transferTo()函数根据指定路径保存图片
        avatarFile.transferTo(dest);
        //更新数据库
        Avatar avatar = new Avatar();
        avatar.setUid(Integer.valueOf(uid));
        avatar.setAvatar(storePath);
        avatar.setUpdateTime(updatedTime);
        //成功返回图片的路径,用于前端图片展示
        return avatarService.saveOrUpdate(avatar)?Result.success(1, storePath):Result.fail("文件上传失败");
    }catch(IOException e){
        e.printStackTrace();
        return Result.fail("文件上传失败");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

效果演示

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/393503
推荐阅读
相关标签
  

闽ICP备14008679号