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

萧仁武 2024-09-30 11:03:01 阅读 91

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

自定义组件 ImageUploadBase64

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

<template>

<div class="component-upload-image">code>

<el-upload ref="imageUploadRef"code>

action="#"code>

list-type="picture-card"code>

accept=".png, .jpeg, .jpg"code>

:limit="limit"code>

:on-change="handleChange"code>

:on-remove="handleRemove"code>

:on-preview="handlePictureCardPreview"code>

:on-exceed="handleExceed"code>

:file-list="fileList"code>

:class="{hide: this.fileList.length >= this.limit}"code>

:show-file-list="true"code>

:auto-upload="false">code>

<i class="el-icon-plus"></i>code>

</el-upload>

<el-dialog :visible.sync="previewDialogVisible" title="图片预览" width="800" append-to-body>code>

<el-image style="display: block; max-width: 100%; margin: 0 auto"code>

:src="previewDialogImageUrl" alt=""></el-image>code>

</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,

// 图片预览 url

previewDialogImageUrl: '',

// 待上传的图片集合 是转化完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); // 转换为Base64

reader.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">code>

// .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">code>

<!-- 添加或修改对话框 -->

<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>code>

<el-form ref="form" :model="form" :rules="rules" :show-message="false" label-width="80px">code>

<el-col :span="24">code>

<el-form-item label="上传图片">code>

<ImageUploadBase64 v-model="form.base64DataList" :file-size="10" @input="handleImageInput"></ImageUploadBase64>code>

</el-form-item>

</el-col>

</el-row>

</el-form>

<div slot="footer" class="dialog-footer">code>

<el-button type="primary" @click="submitForm()">保 存</el-button>code>

<el-button @click="cancel">取 消</el-button>code>

</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: null

base64DataList:[]

};

this.resetForm("form");

},

/** 新增按钮操作 */

handleAdd() {

this.reset();

this.title = "添加工作信息";

this.open = true;

},

/** 修改按钮操作 */

handleUpdate(row) {

this.reset();

const id = row.id || this.ids

getWorkInfo(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> 接收图片的信息并进行后续的处理。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。