当前位置: 首页 > news >正文

【Vue】以RuoYi框架前端为例,ElementUI封装图片上传组件——将图片信息转成base64后提交到后端保存

RuoYi 框架本身对于图片上传功能,在ElementUI<el-upload> 组件的基础装封装了 @/components/ImageUpload/index.vue 组件。本组件就是在 RuoYi 自定义的 <ImageUpload> 组件的基础上进行改造,将图片的信息在上传之前处理成 base64 格式,用于提交到后端接口,以及前端图片相应的预览展示。

自定义组件 ImageUploadBase64

组件目录 : @/components/ImageUploadBase64/index.vue

<template><div class="component-upload-image"><el-upload ref="imageUploadRef"action="#"list-type="picture-card"accept=".png, .jpeg, .jpg":limit="limit":on-change="handleChange":on-remove="handleRemove":on-preview="handlePictureCardPreview":on-exceed="handleExceed":file-list="fileList":class="{hide: this.fileList.length >= this.limit}":show-file-list="true":auto-upload="false"><i class="el-icon-plus"></i></el-upload><el-dialog :visible.sync="previewDialogVisible" title="图片预览" width="800" append-to-body><el-image style="display: block; max-width: 100%; margin: 0 auto":src="previewDialogImageUrl" alt=""></el-image></el-dialog></div>
</template>
<script>export default {props: {// 对应父组件 v-model绑定,对应本组件 this.$emit("input",参数)绑定value: [String, Object, Array],// 图片数量限制limit: {type: Number,default: 5,},// 大小限制(MB)fileSize: {type: Number,default: 5,},// 文件类型, 例如['png', 'jpg', 'jpeg']fileType: {type: Array,default: () => ["png", "jpg", "jpeg"],},},data() {return {// 图片预览弹窗 显隐previewDialogVisible: false,// 图片预览 urlpreviewDialogImageUrl: '',// 待上传的图片集合 是转化完base64 后的结果fileList: [/*{name:'',url:''}*/]}},watch: {value: {handler(val) {if (val) {// 首先将值转为数组const list = Array.isArray(val) ? val : this.value.split(',');// 然后将数组转为对象数组this.fileList = list.map(item => {if (typeof item === "string") {item = {name: item, url: item};}return item;});} else {this.fileList = [];return [];}},deep: true,immediate: true}},methods: {/*** 校验文件尺寸是否符合要求 和类型是否是图片* @param file* @returns {boolean}*/handleFileValidate(file) {// 上传文件的类型let type = file.raw.type || file.type;let isImg = type.indexOf("image") > -1;if (isImg) {if (this.fileSize) {const isLt = file.size / 1024 / 1024 < this.fileSize;if (!isLt) {this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`);return false;} else {return true;}}} else {this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);// 不是图片格式return false;}},/* 添加文件、上传成功和上传失败时都会被调用 */handleChange(file, fileList) {if (this.handleFileValidate(file)) {this.fileToBase64(file);} else {// 删除尺寸大的图片 或者非图片类型的文件let lastIndex = fileList.length - 1;if (lastIndex > -1) {fileList.splice(lastIndex, 1);}}},/*** 删除图片* @param file 被删除的图片* @param fileList 剩余的文件信息列表*/handleRemove(file, fileList) {const findex = this.fileList.map(f => f.url).indexOf(file.url);if (findex > -1) {// 删除对应的 文件数据this.fileList.splice(findex, 1);this.$emit("input", this.listToArray(this.fileList));}},/*预览图片*/handlePictureCardPreview(file) {this.previewDialogImageUrl = file.url;this.previewDialogVisible = true;},/*** 文件个数超出* @param files 超出的文件信息* @param fileList 原来已经添加的文件信息*/handleExceed(files, fileList) {this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);},/*** 将el-upload组件上传的文件转为base64* @param file*/fileToBase64(file) {var reader = new FileReader();reader.readAsDataURL(file.raw); // 转换为Base64reader.onload = e => {// 当转换完成后,e.target.result就是Base64字符串const base64 = e.target.result;this.fileList.push({name: base64, url: base64});this.$emit("input", this.listToArray(this.fileList));};},// list中的元素{name:'',url:''} 转 url字符串listToArray(list) {let arr = [];for (let i in list) {arr.push(list[i].url);}return arr;}}
}</script>
<style scoped lang="scss">
// .el-upload--picture-card 控制加号部分
::v-deep.hide .el-upload--picture-card {display: none;
}// 去掉动画效果
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {transition: all 0s;
}::v-deep .el-list-enter, .el-list-leave-active {opacity: 0;transform: translateY(0);
}
</style>

表单中引用如下

<template><div class="app-container"><!-- 添加或修改对话框 --><el-dialog :title="title" :visible.sync="open" width="500px" append-to-body><el-form ref="form" :model="form" :rules="rules" :show-message="false" label-width="80px"><el-col :span="24"><el-form-item label="上传图片"><ImageUploadBase64 v-model="form.base64DataList" :file-size="10" @input="handleImageInput"></ImageUploadBase64></el-form-item></el-col></el-row></el-form><div slot="footer" class="dialog-footer"><el-button type="primary" @click="submitForm()">保 存</el-button><el-button @click="cancel">取 消</el-button></div></el-dialog></div>
</template><script>
import ImageUploadBase64 from "@/components/ImageUploadBase64/index.vue";import {listWorkInfo, getWorkInfo, delWorkInfo, addWorkInfo, updateWorkInfo} from "@/api/basic/work";export default {name: "Work",components: {ImageUploadBase64},data() {return {// 弹出层标题title: "",// 是否显示弹出层open: false,// 表单参数form: {},};},created() {this.getList();},methods: {/*** 子组件 this.$emit("input", this.listToArray(this.fileList)); 返回的数据* @param fileList*/handleImageInput(fileList){// 这里返回的就是base64字符串的数组,可以直接提交后端接口,也可以根据业务做其他处理console.log("handleImageInput-----:", fileList)},// 取消按钮cancel() {this.open = false;this.reset();},// 表单重置reset() {this.form = {id: nullbase64DataList:[]};this.resetForm("form");},/** 新增按钮操作 */handleAdd() {this.reset();this.title = "添加工作信息";this.open = true;},/** 修改按钮操作 */handleUpdate(row) {this.reset();const id = row.id || this.idsgetWorkInfo(id).then(response => {this.form = response.data;this.open = true;this.title = "修改工作信息";});},/** 提交按钮 */submitForm: function () {this.$refs["form"].validate(valid => {if (valid) {if (this.form.id != undefined) {updateWorkInfo(this.form).then(response => {this.$modal.msgSuccess("修改成功");this.open = false;this.getList();});} else {addWorkInfo(this.form).then(response => {this.$modal.msgSuccess("新增成功");this.open = false;this.getList();});}}});}}
};
</script>

这个组件将图片信息直接在前端转化成 base64格式的字符串数字,后端可以直接使用List<String> 接收图片的信息并进行后续的处理。

相关文章:

  • 盛事启幕 | 第三届OpenHarmony技术大会重磅官宣,邀您共绘智联未来
  • 深度学习模型可视化工具 Netron 使用教程
  • AndroidStudio依赖报错
  • Qt QIntValidator详解
  • 【以图搜图代码实现2】--faiss工具实现犬类以图搜图
  • 2024/9/30 英语每日一段
  • GORM CRUD
  • Flux【真人模型】:高p高糊反向真实质感!网图风格的Lora模型,超逼真的AI美女大模型!
  • C#测试调用Ghostscript.NET浏览PDF文件
  • 用户体验测试——什么是用户体验?
  • Axure9破解
  • iOS实现解压文件
  • 【C++篇】启航——初识C++(下篇)
  • 如何从huggingface下载
  • .NetCore 8 SwaggerGen 显示接口注析
  • [js高手之路]搞清楚面向对象,必须要理解对象在创建过程中的内存表示
  • Brief introduction of how to 'Call, Apply and Bind'
  • JavaScript 基础知识 - 入门篇(一)
  • JavaScript实现分页效果
  • Mysql优化
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • php ci框架整合银盛支付
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • Vue2.x学习三:事件处理生命周期钩子
  • vue-router 实现分析
  • 前端知识点整理(待续)
  • 如何解决微信端直接跳WAP端
  • 入门级的git使用指北
  • 深度学习中的信息论知识详解
  • 通过几道题目学习二叉搜索树
  • 想使用 MongoDB ,你应该了解这8个方面!
  • 白色的风信子
  • 阿里云IoT边缘计算助力企业零改造实现远程运维 ...
  • # linux 中使用 visudo 命令,怎么保存退出?
  • # 安徽锐锋科技IDMS系统简介
  • # 数仓建模:如何构建主题宽表模型?
  • # 数据结构
  • (1)svelte 教程:hello world
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (剑指Offer)面试题34:丑数
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (一)RocketMQ初步认识
  • (转)fock函数详解
  • *算法训练(leetcode)第三十九天 | 115. 不同的子序列、583. 两个字符串的删除操作、72. 编辑距离
  • .NET C# 操作Neo4j图数据库
  • .Net Core中Quartz的使用方法
  • .Net MVC + EF搭建学生管理系统
  • .NET开源、简单、实用的数据库文档生成工具
  • // an array of int
  • @antv/x6 动态的修改attr与prop,以及动态改变节点的大小
  • @requestBody写与不写的情况
  • [] 与 [[]], -gt 与 > 的比较
  • [AI Google] 使用 Gemini 取得更多成就:试用 1.5 Pro 和更多智能功能
  • [BZOJ 1032][JSOI2007]祖码Zuma(区间Dp)