本人业余前端开发,因为公司(很坑)觉得我很牛逼,所以让我前后端一起玩,无奈的我只能磕磕碰碰的研究起了vue

开发项目的时候,用到文件上传的功能很常见,包括单文件上传和多文件上传,上传各种类型的文件。在vue里面要实现多文件上传功能,还是很方便的。

本文就一起来学习一下,如何把多文件上传功能封装成一个组件,后面需要使用的时候,直接两三行代码就能搞定。

1、前端代码

首先我们先看前端,如何把它封装成一个组件。我们在调用它的时候,可能需要从外部传入一些参数给它,所以我们需要定义一些传入参数。这些参数我们可以放到props里面

export default {
props: {
// 值
value: [String, Object, Array],
// 大小限制(MB)
fileSize: {
type: Number,
default: 2,
},
// 文件类型, 例如['png', 'jpg', 'jpeg']
fileType: {
type: Array,
default: () => [".jpg", ".jpeg", ".png", ".doc", ".xls", ".xlsx", ".ppt", ".txt", ".pdf"],
},
// 是否显示提示
isShowTip: {
type: Boolean,
default: true
},
// 单据id
billId: {
type: Number,
require: true
},
// 单据类型
billType: {
type: Number,
required: true
}
}
}

上面定义了一些文件大小,文件类型等,如果没有传入,则为默认值。单据类型和单据id是必须要传入的,这里可以依照实际开发需要进行定义即可。

文件上传组件,我们可以使用element的el-upload,在页面引入,我们点击后一般唤醒的是一个文件上传弹窗,可以使用el-dialog标签包围。完整代码如下

<template>
<el-dialog title="附件上传" :visible.sync="visible" width="800px" :close-on-click-modal="false" @close="cancel">
<div class="upload-file">
<el-upload
:action="action"
:before-upload="handleBeforeUpload"
:file-list="fileList"
:limit="3"
multiple
:accept="accept"
:on-error="handleUploadError"
:on-exceed="handleExceed"
:on-success="handleUploadSuccess"
:on-change="handChange"
:http-request="httpRequest"
:show-file-list="true"
:auto-upload="false"
class="upload-file-uploader"
ref="upload"
>
<!-- 上传按钮 -->
<el-button slot="trigger" size="mini" type="primary">选取文件</el-button>
<el-button style="margin-left: 10px;" :disabled="fileList.length < 1" size="small" type="success" @click="submitUpload">上传到服务器</el-button>
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
请上传
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
的文件
</div>
</el-upload> <!-- 文件列表 -->
<transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
<li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in list">
<el-link :href="file.url" :underline="false" target="_blank">
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
</el-link>
<div class="ele-upload-list__item-content-action">
<el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
</div>
</li>
</transition-group>
</div>
</el-dialog>
</template>

上面用到的几个变量,我们需要在data里面定义

data() {
return {
// 已选择文件列表
fileList: [],
// 是否显示文件上传弹窗
visible: false,
// 可上传的文件类型
accept: '',
action: 'action'
};
},

accept字段需要在页面创建后,通过传入或默认的fileType字段进行拼接得到

created() {
this.fileList = this.list
// 拼接
this.fileType.forEach(el => {
this.accept += el
this.accept += ','
})
this.fileType.slice(0, this.fileList.length - 2)
},

接下来就是文件上传相关的方法,这里我们使用选择文件后手动上传的方式,请看下面的代码

<el-upload
:action="action" // 手动上传,这个参数没有用,但因为是必填的,所以随便填一个值就行
:before-upload="handleBeforeUpload" // 文件上传之前进行的操作
:file-list="fileList" // 已选择文件列表
:limit="3" // 一次最多上传几个文件
multiple // 可以多选
:accept="accept" // 可以上传的文件类型
:on-error="handleUploadError" // 上传出错时调用
:on-exceed="handleExceed" // 文件数量超过限制时调用
:on-success="handleUploadSuccess" // 上传成功时调用
:on-change="handChange" // 文件发生变化时调用
:http-request="httpRequest" // 自定义的文件上传方法,我们手动点击上传按钮后会调用
:show-file-list="true" // 是否显示文件列表
:auto-upload="false" // 关闭自动上传
class="upload-file-uploader"
ref="upload"
> <!-- 上传按钮 -->
<el-button slot="trigger" size="mini" type="primary">选取文件</el-button>
<el-button style="margin-left: 10px;" :disabled="fileList.length < 1" size="small" type="success" @click="submitUpload">上传到服务器</el-button>

点击上传到服务器后,就触发submitUpload调用我们自定义的方法。

注意这里选取文件的按钮需要加上slot="trigger"属性,不然点击上传到服务器按钮后,也会触发选择文件弹框。

接下来看相关的方法

methods: {
// 外部调用这个方法,显示文件上传弹窗
show() {
this.visible = true
},
// 上传前校检格式和大小
handleBeforeUpload(file) {
// 校检文件类型
if (this.fileType) {
let fileExtension = "";
if (file.name.lastIndexOf(".") > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf("."));
}
const isTypeOk = this.fileType.some((type) => {
if (file.type.indexOf(type) > -1) return true;
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
return false;
});
if (!isTypeOk) {
this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
return false;
}
}
// 校检文件大小
if (this.fileSize) {
const isLt = file.size / 1024 / 1024 < this.fileSize;
if (!isLt) {
this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
return false;
}
}
return true;
},
// 文件个数超出
handleExceed() {
this.$message.error(`只允许上传3个文件`);
},
// 上传失败
handleUploadError(err) {
this.$message.error("上传失败, 请重试");
},
// 上传成功回调
handleUploadSuccess(res, file) {
this.$message.success("上传成功");
this.cancel()
},
/** 文件状态改变时调用 */
handChange(file, fileList) {
this.fileList = fileList
},
// 删除文件
handleDelete(index) {
this.fileList.splice(index, 1);
},
// 获取文件名称
getFileName(name) {
if (name.lastIndexOf("/") > -1) {
return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
} else {
return "";
}
},
/** 手动提交上传 */
submitUpload() {
if (this.fileList.length <= 0) {
return false
}
this.$refs.upload.submit()
},
/** 关闭上传弹框 */
cancel() {
this.fileList = []
this.visible = false
},
/** 调用接口上传 */
httpRequest(param) {
const formData = new FormData()
formData.append("billId", this.billId)
formData.append("formType", this.billType)
formData.append('file', param.file)
uploadFormFile(formData).then(res => {
if(res.code === 200){
// 自定义上传时,需自己执行成功回调函数
param.onSuccess()
this.$refs.upload.clearFiles()
this.msgSuccess("上传成功")
// 回调方法,文件上传成功后,会调用`input`指定的方法,在调用方定义
this.$emit("input", res.data)
}
}).catch((err)=>{})
}
}

其他方法都还好,主要看看这个httpRequest方法,如果直接使用url的方式进行调用,会出现跨域问题,你需要把token放到请求头里。我这里是通过封装后的api接口进行调用的,已经做了全局的token验证,所以只需要把相关的参数带上即可。

使用formData 带上需要的参数。上传成功后,使用this.$emit("input", res.data)执行上传成功后的逻辑。

这就封装好了一个文件上传的组件,接下来看看怎么使用。

2、使用组件

在使用的页面,首先需要引入组件

import FileUpload from '@/components/FileUpload'

然后再页面内进行调用

<file-upload ref="fileUploadDialog" :billId="this.form.noticeId" :billType="10" @input="getAttachList"></file-upload>

billIdbillType是我们动态传入的参数,其他的参数使用默认值,getAttachList方法在文件上传成功后执行。

我们需要一个按钮唤醒文件上传框

<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="handleAdd"
:disabled="notEdit"
>上传</el-button>

定义hangAdd方法,直接调用组件里定义的show方法即可

handleAdd() {
this.$refs.fileUploadDialog.show()
},

然后定义文件上传成功后的方法,获取已上传文件列表即可。

 getAttachList() {
this.loading = true
this.attachQuery.billId = this.form.noticeId
this.attachQuery.billType = 10
listAttachment(this.attachQuery).then(response => {
this.attachList = response.rows
this.attachList.forEach(el => {
// 转为kb,取小数点后2位
el.fileSize = parseFloat(el.fileSize / 1024).toFixed(2)
})
this.attachTotal = response.total
this.loading = false
}).catch(() => {})
},

到这里前端代码就大功告成了。

3、后端代码

我这里选择上传图片到阿里云服务器,上传到哪里不重要

/**
* 单据附件上传
* @param billId 单据id
* @param formType 单据类型
* @param file 上传的文件
* @return
* @throws Exception
*/
@PostMapping("/form/attachment/upload")
public AjaxResult uploadFormFile(@RequestParam(value = "billId") Long billId,
@RequestParam(value = "formType") Integer formType,
@RequestParam("file") MultipartFile[] file) throws Exception {
try {
// 文件上传后的路径
List<String> pathList = new ArrayList<>(); for (MultipartFile f : file) {
if (!f.isEmpty()) {
// 调用接口上传照片
AjaxResult result = uploadService.uploadFormFile(f, billId, formType);
if (!result.get("code").toString().equals("200")) {
return AjaxResult.error("上传文件异常,请联系管理员");
}
pathList.add(result.get("data").toString());
}
} // 返回图片路径
return AjaxResult.success(pathList);
} catch (Exception e) {
return AjaxResult.error(e.getMessage());
}
}

这里我们使用一个MultipartFile数组接受文件,然后调用方法判断文件的一些属性上传文件即可,具体的上传方法这里就不贴了,各有不同,具体情况具体分析。

到这里,本文就ok了。关于MIME 类型列表,可以点击这里查看。如果过程中遇到什么问题,可以在下方留言,我会回复的。

觉得好的可以帮忙点个赞啊,也可以关注我的公众号【秃头哥编程】

Vue实现多文件上传功能(前端 + 后端代码)的更多相关文章

  1. 使用element的upload组件实现一个完整的文件上传功能(上)

    说到标题就有点心塞了,前段时间项目上需要实现一个文件上传的功能,然后就咔咔的去用了element的upload组件,不用不知道一用吓一跳哇. 在使用的过程中遇到了很多让意想不到的问题,后来也因为时间问 ...

  2. 使用element的upload组件实现一个完整的文件上传功能(下)

    本篇文章是<使用element的upload组件实现一个完整的文件上传功能(上)>的续篇. 话不多说,接着上一篇直接开始 一.功能完善—保存表格中每一列的文件列表状态 1.思路 保存表格中 ...

  3. vue之element-ui文件上传

    vue之element-ui文件上传 文件上传需求 ​ 对于文件上传,实际项目中我们的需求一般分两种: 对于单个的文件上传,比如拖动上传个图片之类的,或者是文件. 和表单一起实现上传(这种情况一般都是 ...

  4. 文件/大文件上传功能实现(JS+PHP)全过程

    文件/大文件上传功能实现(JS+PHP) 参考博文:掘金-橙红年代 前端大文件上传 路漫漫 其修远 PHP + JS 实现大文件分割上传 本文是学习文件上传后的学习总结文章,从无到有实现文件上传功能, ...

  5. vue+axios+elementUI文件上传与下载

    vue+axios+elementUI文件上传与下载 Simple_Learn 关注  0.5 2018.05.30 10:20 字数 209 阅读 15111评论 4喜欢 6 1.文件上传 这里主要 ...

  6. iOS 的 Safari 文件上传功能详解

    iOS 6 给 Safari 浏览器带来的另外一个功能是文件上传,终于 Safari 终于支持 input 输入框的文件类型了,并且还支持 HTML媒体捕获(HTML Media Capture). ...

  7. [php基础]PHP.INI配置:文件上传功能配置教程

    昨天分享了在PHP网站开发中如何在php.ini中配置实现session功能的PHP教程,今天继续分享在利用PHP实现文件上传功能时几点关键php.ini的配置. 说到在php.ini中的文件上传的配 ...

  8. 达到HTTP合约Get、Post和文件上传功能——采用WinHttp介面

    于<采用WinHttp实现HTTP协议Get.Post和文件上传功能>一文中,我已经比較具体地解说了怎样使用WinHttp接口实现各种协议. 在近期的代码梳理中,我认为Post和文件上传模 ...

  9. 学习ASP.NET Core Razor 编程系列十五——文件上传功能(三)

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

随机推荐

  1. 编译aarch64 Linux内核并基于qemu运行

    核心流程 首先,本文主要讲述如何编译Linux内核并在qemu虚拟机上运行.这里针对的架构是aarch64. 本文的实验平台是Ubuntu 16.04. 为了达成目标,我们需要有qemu.buildr ...

  2. mybatis框架学习第一天

    三层架构: 表现层:用于展示数据 业务层:处理业务需求 持久层:和数据库交互的 3.持久层技术解决方案: JDBC技术: Connecction PreparedStatement ResultSet ...

  3. 第一章python 简介

    python语言是目前最流行的编程语言之一,在笔者写这篇文章的前一周,2018年的IEEE的编程语言排行出来了,python又雄踞第一. Python 强势霸榜第一名!排名第二的 C++ 得分是 98 ...

  4. YAOI Round #7 题解

    前言 比赛链接: Div.1 : http://47.110.12.131:9016/contest/16 Div.2 : http://47.110.12.131:9016/contest/15 D ...

  5. C语言:if条件写法

    if 语句的判断条件中不是必须要包含关系运算符,它可以是赋值表达式,甚至也可以是一个变量,常量 例如: //情况① if(b){ //TODO: } //情况② if(b=5){ //情况① //TO ...

  6. Java基础00-数据输入5

    1. 数据输入 1.1 数据输入概述 我们需要的数据(比如账号密码)并不是一开是就有的,而是要输入的. 1.2 Scanner使用的基本步骤 1.3 案例

  7. Docker与k8s的恩怨情仇(五)——Kubernetes的创新

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 上节中我们提到了社区生态的发展使得Kubernetes得到了良性的发展和传播.比起相对封闭的Docker社区 ...

  8. ES6 对象定义简写及常用的扩展方法

    1.ES6 对象定义简写 es6提供了对象定义里的属性,方法简写方式: 假如属性和变量名一样,可以省略,包括定义对象方法function也可以省略 <script type="text ...

  9. 记一次lombok踩坑记

    引言 今天中午正在带着耳机遨游在代码的世界里,被运营在群里@了,气冲冲的反问我最近有删生产的用户数据的吗?我肯定客气的回答道没有呀?生产的数据我怎么能随随便便可以删除,这可是公司的红线,再说了我也没有 ...

  10. PostgreSQL数据库结构

    PG数据存储结构分为:逻辑结构和物理存储. 一.逻辑存储结构是:内部的组织和管理数据的方式[逻辑存储结构适用于不同的操作系统和硬件平台] 二.物理存储结构是:操作系统中组织和管理数据的方式. 1.逻辑 ...