2

#yyds干货盘点#前端如何通过antdv组件上传文件

 2 years ago
source link: https://blog.51cto.com/u_12880763/5068832
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

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

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

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

这里用的是Ant Design VueUpload组件;

1. 组件介绍

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

参数 说明 类型 默认值

accept 接受上传的文件类型, 详见  input accept Attribute string 无

action 上传的地址 string|(file) => Promise

beforeUpload 上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传。 (file, fileList) => `boolean Promise`

customRequest 覆盖默认的上传行为,实现自己的上传方式 Function 无

remove 点击移除文件时的回调,返回值为 false 时不移除 Function(file): `boolean Promise`

multiple 是否支持多选文件 boolean false

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已经不是自定义的上传文件属性了,所以系统还会去找默认的上传路径;

#yyds干货盘点#前端如何通过antdv组件上传文件_上传文件

解决办法:就是给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属性;

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

但就是需要配合;


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK