vue写一个简单的文件上传控件

2022年5月17日12:47:55

这篇将介绍如何写一个简单的基于Vue+Element的文件上传控件。

控件将具有

1. 上传队列的列表,显示文件名称,大小等信息,可以显示上传进度实时刷新

2. 取消上传

vue写一个简单的文件上传控件vue写一个简单的文件上传控件

 使用Element的uploader控件,上传文件的行为和样式不用自己全部实现,使代码简化。且有足够的扩展性,文件传输请求的代码可以基于axios完全自己重写。我们只用关心核心代码。

搭建项目框架

首先建立一个空白的项目,引入Element控件库,具体的操作和使用Element控件库请看官方文档:

组件 | Element

后端项目框架的搭建,请阅读:[.Net 6]写一个简单的文件上传控件后端 - 林晓lx - 博客园 (cnblogs.com)

编写文件上传代码

编写文件上传的帮助类,新建ajaxRequire.ts并键入以下内容:

import axios, {CancelTokenSource }from'axios'//发送网络请求exportconst request =async (url:string, methods,data:any, onProgress?:(e)=>void, cancelToken?:CancelTokenSource) => {let token =nulllet timeout =3000;if (cancelToken) {
        token = cancelToken.token
        timeout =0;
    }const service = axios.create()const re =await service.request({headers: {'Content-Type':'multipart/form-data'},url: url,method: methods,data: data,cancelToken: token,timeout: timeout,onUploadProgress:function (progressEvent) {//原生获取上传进度的事件if (progressEvent.lengthComputable) {if (onProgress) {onProgress(progressEvent);
                }
            }
        },
    })return reasany;
}///获得取消令牌exportconstgetCancelToken = () => {const source = axios.CancelToken.source();return source;
}

vue写一个简单的文件上传控件

onUploadProgress回调函数将在数据传输进度变化的时候触发,携带progressEvent 原生获取上传进度事件参数,progressEvent.lengthComputable用于判断是否可以进行进度计算

axios.CancelToken.source()可以获得一个源,这个源包含一个唯一Id用于标识哪个请求,和一个cancel函数用于取消请求

编写控件

在App.vue中添加核心的控件 <el-upload>

接着添加属性,注意我们将用自己的方法upload替换el-upload中的上传操作,因此设置action="/",

:http-request="upload",如下:

<el-uploadref="upload":limit="10"multipleaction="/":http-request="upload"></el-upload>

vue写一个简单的文件上传控件

在script中添加上传Dto:一些业务相关的数据在这里定义 比如ownerUserId, fileContainerName等,这些数据可以通过表单与文件数据一并上传

exportclassCreateFileDto {id:string;fileContainerName:string;//文件夹名称parentId:string;//文件的父IdownerUserId:number;//文件的归属用户IdfileName:string;mimeType:string;fileType:number;//文件类型 0:文件夹,1:普通文件file:any;//文件数据
}

vue写一个简单的文件上传控件

method中添加一些帮助类函数:

methods: {successMessage(value ="执行成功") {this.$notify({title:"成功",message: value,type:"success",
      });
    },errorMessage(value ="执行错误") {this.$notify.error({title:"错误",message: value,
      });
    },FriendlyFileSize(bytes) {
      bytes =parseFloat(bytes);if (bytes ===0)return"0B";let k =1024,
        sizes = ["B","KB","MB","GB","TB"],
        i =Math.floor(Math.log(bytes) /Math.log(k));return (bytes /Math.pow(k, i)).toPrecision(3) + sizes[i];
    },
}

vue写一个简单的文件上传控件

编写提交前置函数,这里将做验证和生成cancelToken:

beforeUpload(file) {var token =getCancelToken();
      file.cancelToken = token;let isLt2M =true;if (this.fileSizeLimit <0) {returntrue;
      }
      isLt2M = file.size /1024 /1024 <this.fileSizeLimit;if (!isLt2M) {this.loading =false;this.errorMessage(`"上传文件大小不能超过${this.fileSizeLimit}}MB!"`);
      }return isLt2M;
}

vue写一个简单的文件上传控件

 编写upload函数,用于组装请求数据并交给 ajaxRequire 执行上传任务

asyncupload(option) {this.loaded =true;var model =newCreateFileDto();var file = option.file;
      model.fileName = file.name;
      model.fileType =2;
      model.mimeType = file.type;
      model.ownerUserId =1;
      model.fileContainerName ="Container1";
      model.file = file;var fd =newFormData();Enumerable.from(model).forEach((c) => {
        fd.append(c.key, c.value);
      });var token = file.cancelToken;awaitrequest(this.uploadUrl,"post",
        fd,(e) => {if (e.total >0) {
            e.percent = (e.loaded / e.total) *100;
          }
          option.onProgress(e);
        },
        token
      );
    },

vue写一个简单的文件上传控件

将token将作为取消传输的入口交给ajaxRequire ,自己也保留这个对象用于发送取消命令,相当于“一式两份”。

添加el-upload各阶段函数的订阅

:before-upload="beforeUpload"
:on-success="handleSuccess"
:on-remove="handleRemove"
:on-error="handleError"

handleSuccess(response, file, fileList) {this.successMessage("上传成功");this.loading =false;
    },handleError(e, file, fileList) {this.errorMessage(e);this.loading =false;
    },handleRemove(file, fileList) {if (file.raw.cancelToken) {
        file.raw.cancelToken.cancel();
      }
    },

vue写一个简单的文件上传控件

编写上传队列的Html代码:

<el-buttonref="uploadButton">上传</el-button><spanslot="file"slot-scope="{ file }"><divclass="filelist-item"><el-row><el-col:span="6"class="file-icon-frame"><iclass="el-icon-document file-icon"></i></el-col><el-col:span="18"><el-row><el-col:span="20"><labelclass="file-title">
                    {{ file.name }}</label></el-col><el-col:span="4"style="text-align: right"><el-buttontype="danger"icon="el-icon-minus"size="mini"circle
                    @click="handleRemove(file)"
                  ></el-button></el-col><el-col:span="24"><labelclass="file-size">
                    {{ FriendlyFileSize(file.size) }}</label></el-col><el-col:span="24"><el-progress:text-inside="true":stroke-width="26":percentage="parseInt(file.percentage, 10)":status="
                      parseInt(file.percentage, 10) == 100 ? 'success' : ''
                    "
                  >
                  </el-progress
                ></el-col></el-row></el-col></el-row></div></span>

vue写一个简单的文件上传控件

运行

进入后端项目的目录(api),运行:

dotnet run

vue写一个简单的文件上传控件

前端项目目录(web),运行

yarn serve

vue写一个简单的文件上传控件

运行效果:

vue写一个简单的文件上传控件vue写一个简单的文件上传控件

完整代码:

file-uploader-sample/web at master · jevonsflash/file-uploader-sample (github.com)

项目地址:

jevonsflash/file-uploader-sample (github.com)

  • 作者:林晓lx
  • 原文链接:https://www.cnblogs.com/jevonsflash/p/16169944.html
    更新时间:2022年5月17日12:47:55 ,共 4258 字。