【ant-design】-upload组件个性化实现上传文件

【ant-design】-upload组件个性化实现上传文件,第1张

一、项目需求

要求: 可通过点击灰色区域打开系统的文件选择器,或将文件选择窗口中的文件拖动到灰色区域实现选择文件;文件在选择中限制可选择的文件类型并且不可选择文件夹;选择文件之后,列表显示选择的文件【文件名+删除按钮】;选择文件后,不立刻实现文件上传,在用户点击确定按钮之后,将文件以列表的方式上传到后端。 二、实现分析 首先我们的项目是angular并且使用ant-design的组件库,所以选用ant-design 的upload 组件。
<div class="content">
      
      <nz-upload
        nzType="drag"
        nzAccept=".zip,.lic"
        [nzMultiple]="true"
        [nzBeforeUpload]="beforeUpload">
        <div class="uploadBtn">
          <div class="center">
            <input id="uploadPut" type="file" style="display: none"/>
            <div class="upload-img">
              <img src="assets/icon/file-update.png" alt="文件上传" style="height: 66px"/>
            div>
            <div class="upload-text">
              单击或拖动文件到该区域进行上传
            div>
          div>
        div>
      nz-upload>
      
      <ul class="upload-list">
        <li class="upload-item" *ngFor="let checkItem of checkFiles;let i=index">
          <span style="font-size: 16px">{{checkItem.name}}span>
          <span class="progress">span>
          <span class="icon" style="font-size: 16px">
            <i nz-icon nzType="delete" nzTheme="twotone" (click)="delCheckItem(i)">i>
          span>
        li>
      ul>
    div>
    
    <div class="btn-box">
      <button nz-button nzType="primary" (click)="submit()">确认button>
      <button nz-button nzType="default" (click)="onCancel()">取消button>
    div>
方法解析
  // 文件列表
  checkFiles: File[] = [];
  constructor( private authManageService: AuthManageService) {}
   /**
   * 1.文件上传之前
   */
  beforeUpload = (file, fileList) => {
    // 1.2将没有重复的文件添加到列表
    const reArr = this.checkFiles.filter(checkItem => checkItem.name === file.name);
    if (reArr.length <= 0) {
      // 1.1限制文件类型
      const nameStr = file.name.toLocaleLowerCase();
      const typeStr = file.type.toLocaleLowerCase();
      const reg1 = /\.(zip|lic)$/;
      const reg2 = /zip|lic/;
      if (reg1.test(nameStr) || typeStr.match(reg2)) {
        this.checkFiles.push(file);
      } else {
        this.message.create('error', `${file.name}文件不符合,请上传.zip或.lic格式的文件`);
      }
    }
    // 1.0停止组件的自定义上传
    return false;
  }
  /**
   * 删除当前文件
   */
  delCheckItem(i: number): void {
    this.checkFiles.splice(i, 1);
  }
  /**
   * 提交授权文件
   */
  submit(): void {
    if (this.checkFiles.length <= 0) {
      this.message.info('请先上传文件!');
    }
    // 处理post提交的格式
    const params = new FormData();
    this.checkFiles.forEach(item => {
      params.append('multipartFile', item);
    });
    // 执行添加的 *** 作
    this.http.post('url', params).then(res,err);
  }
三、问题:

1. 在打开文件进行选择的时候,我们发现,限制选择文件类型并不是被系统完全限制的,它还是可选择所有文件。因此此处为了加强用户体验,我尝试找了处理的方法:

【1】网页中的打开文件行为实质是浏览器触发了文件选择的事件;
【2】浏览器对象模型(BOM)的核心是window对象;
【3】在谷歌浏览器的window对象,发现了 showOpenFilePicker() 方法;
【4】最后,通过在mdn上的查找,发现 showOpenFilePicker() 的作用如下:

我们可以通过将【excludeAcceptAllOption】值设为true,来禁止对所有文件的选择。

2. 但是,这并没有结束;兼容性问题始终是程序处理的难题。

在实际项目中;如果项目对于浏览器的兼容性要求没那么严格,并且项目最终应用到的浏览器属于谷歌86版本及以上、Edge版本86及以上或者欧朋版本72及以上,那么我们可以尝试使用这个方法来个性化定制打开文件选择器的功能。

注意:1. 我遇到的项目是客户端,内核是谷歌的83版本,因此当时使用时直接报错window下找不到这个方法。因此,在不确定的情况下,我们可以查看一下浏览器的内核及版本:

/**
* BOM 在 navigator 对象中定义了 userAgent 属性,
* 利用该属性可以捕获客户端 user-agent(用户代理) 字符串信息。
*/
var s = window.navigator.userAgent;
  //简写方法
var s = navigator.userAgent;
console.log(s);
/**
* 返回类似信息:
* Mozilla/5.0 (Windows NT 10.0; Win64; x64)
* AppleWebKit/537.36 (KHTML, like Gecko) 
* Chrome/77.0.3865.90 Safari/537.36
*/

检测原理: 客户端浏览器每次发送 HTTP 请求时,都会附带有一个 user-agent(用户代理)字符串,对于 Web 开发人员来说,可以使用用户代理字符串检测浏览器类型。

注意:2.在 angular 组件中使用 Window.showOpenFilePicker() 时,可能是因为语法检测,不可以直接使用;需要用:(Window as any)将 winddow 进行一次类型转换。

(Window as any).showOpenFilePicker({
  // 类型限制
  types: [
    {
      description: 'Images',
      accept: {
        'image/*': ['.png', '.gif', '.jpeg', '.jpg']
      }
    },
  ],
  // 是否排除选择所有文件
  excludeAcceptAllOption: true,
  // 是否可多选文件
  multiple: true
})

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1296603.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存