侧边栏壁纸
  • 累计撰写 79 篇文章
  • 累计创建 84 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

前端如何通过antdv组件上传文件

汤圆学Java
2022-02-08 / 0 评论 / 0 点赞 / 70 阅读 / 4,797 字
温馨提示:
本文最后更新于 2022-02-08,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

上传文件到云存储一般有两种方式:前端上传和后端上传;

前端上传就是前端自己上传到OSS云存储,然后将远程链接传给后端;

后端上传就是前端只负责上传本地文件,然后后端酌情处理,可以上传到云存储,也可以本地存储;

因为andtv官方的例子就是介绍的第二种,所以本篇我们来介绍第一种方式,前端自己上传到云存储;

这里用的是Ant Design VueUpload组件;

目录

  1. 组件介绍
  2. 上传例子
  3. 踩坑记录

正文

1. 组件介绍

Upload组件有很多属性,这里我们只关注下面几个即可:

参数说明类型默认值
accept接受上传的文件类型, 详见 input accept Attributestring
action上传的地址string|(file) => Promise
beforeUpload上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传。(file, fileList) => boolean | Promise
customRequest覆盖默认的上传行为,实现自己的上传方式Function
remove点击移除文件时的回调,返回值为 false 时不移除Function(file): boolean | Promise
multiple是否支持多选文件booleanfalse
fileList已经上传的文件列表object[]
  • accept:因为本篇我们只需要上传PDF文件,所以这里的accept=.pdf
  • action:接受一个后端地址作为属性值,本地文件会被上传到指定的地址进行处理;
  • beforeUpload:这个属性会在选中文件后,上传文件前触发;这里的作用主要是为了获取上传的文件列表
  • customRequest:它是本篇的核心,就是覆盖原有的action操作,自己实现特定的上传方式,比如上传到阿里云、其他云等等
  • fileList:配合beforeUpload,用来展示已经上传的文件列表

这个Upload组件内部有一个隐藏的元素,用来展示已经上传的文件列表;

没有上传文件时,该元素不会显示;

当上传了文件后,该元素会显示上传的文件列表;

2. 上传例子

下面我们就开始写这个自定义上传的例子,代码只展示了关键部分

html部分如下:

<a-upload accept=".pdf" :file-list="fileList" :remove="handleRemove" :before-upload="beforeUpload" :customRequest="handleUpload">
    <a-button> <a-icon type="upload" /> 点击上传文件(仅支持PDF格式)</a-button>
</a-upload>

js部分如下:

handleRemove(file) {
    const index = this.fileList.indexOf(file);
    const newFileList = this.fileList.slice();
    newFileList.splice(index, 1);
    this.fileList = newFileList;
},

beforeUpload(file, fileList) {
    this.fileList = fileList
    console.log('file:', file)
    console.log('fileList:', fileList)
    return true;
},

handleUpload(data) {
    console.log(data)
    const _this = this
    const file = data.file
    if(file){
        client.put('pdf/'+file.name, file).then(res=>{
            console.log('结果:', res)
            _this.detailNew = Object.assign({}, this.detailNew, {filePath: res.url})
        })
    }else{
        console.error('没有选择文件')
    }
},

阿里云上传接口,其他云存储的接口类似,都是创建一个客户端对象,然后在需要的地方引入使用

import OSS from 'ali-oss';
const client=new OSS({
    region: '***',
    accessKeyId: '***',
    accessKeySecret: '***',
    bucket: '***'
})

export {client}

然后在提交表单时,直接post提交this.detailNew对象即可,该对象内部包含了文件的云存储路径

3. 踩坑记录

  1. customRequest赋值问题

如果给属性customRequest赋值为handleUpload(data),而不是函数名handleUpload

那么vue的任意一个属性每刷新一次,就会触发一次handleUpload(data)函数的执行;

因为这里给customRequest赋值的不是函数,而是函数的代码块;

当视图初始化时,会先触发一次函数的执行;

然后在后面的视图刷新时,还会不断的触发;

而且当你上传了文件,还会提示400错误,因为这时的customRequest已经不是自定义的上传文件属性了,所以系统还会去找默认的上传路径;

image-20220208160920004

解决办法:就是给customRequest赋值时,要赋值一个函数名,而不是函数名+参数;不然该属性的值就会变成函数的执行代码块,然后每触发一次,就自动执行一次

这里有个疑问就是为啥不把customRequest设置成事件呢?事件感觉更合理一些;感觉上面的属性都可以设置成事件

  1. beforeUpload的返回值问题

beforeUpload的返回值如果是false,则表示停止上传;

刚开始我的理解是停止默认的上传,所以我就返回false;

然后当我上传了文件后,发现死活触发不了customRequest中的自定义上传;

改为true后,发现就上传成功了,说明这里的false指的是停止后续所有的上传操作,包括默认的上传和自定义的上传;

解决办法:只有在不需要上传文件时,才可以设置成false返回;多测试,多理解;

  1. 上传进度没显示

这是因为我们用了自定义的上传方式,所以默认的上传进度就失效了;

默认的上传进度可以在@change中监听变化事件,然后根据文件上传后服务器的响应来进行处理,如果返回200,则成功,返回错误则失败;

所以这里的上传进度需要我们自己实现,我们可以直接在上传按钮上添加一个loading属性:

  • 开始上传时,设置为true;

  • 上传完成时,设置为false;

<a-button  :loading="loading"> <a-icon type="upload" /> 点击上传文件(仅支持PDF格式)</a-button>

在beforeUpload中设置为true:

beforeUpload(file, fileList) {
    this.fileList = fileList
    console.log('file:', file)
    console.log('fileList:', fileList)
    this.loading = true
    return true;
},

在上传到阿里云后,设置为false:

handleUpload(data) {
    console.log(data)
    const _this = this
    const file = data.file
    if(file){
        client.put('pdf/'+file.name, file).then(res=>{
            console.log('结果:', res)
            _this.detailNew = Object.assign({}, this.detailNew, {filePath: res.url})
            _this.loading = false
        })
    }else{
        console.error('没有选择文件')
    }
},

总结

本篇主要介绍了通过antdv的upload组件,实现自定义上传文件到云存储的方法,核心就是customRequest属性;

默认的上传其实是最方便的,前端只需要把本地文件传给后端就可以了,后端再去上传文件到各种云;

但就是需要配合;

0

评论区