亲宝软件园·资讯

展开

使用element-ui的upload组件上传代码包时遇到的问题小结

遛狗先生 人气:0

1.在工作中使用element-ui的upload组件时,遇到一个问题就是这个upload会自动发送一个http请求,即使你使用了http-request自定义上传覆盖默认上传函数,也会导致在控制台里多出一个请求,并且当项目中使用proxy代理挂载到原型上类似的请求接口方法的时候,必须知道原请求路径放在他的actions属性中,才可以使它的多余请求不报错,可能说的有一些混乱,接下来用代码演示:

export function proxy (interfaceId, proxyOptions = {}) {
  return (data = {}, options = {}) => {
    let config = Object.assign({}, proxyOptions, options)
    return app.api.rpc(interfaceId, data, config)
  }
}

2.在项目中使用类似的接口处理函数的时候,此时的actions里面应该填写要请求的服务器地址,但是项目中已经把请求封装且做了统一处理的时候,这个actions就基本不会再去使用它,就算使用也得加上很多环境使用的判断条件,actions的局限性由此体现了出来,但是element-ui的官方又给了http-request的方法可以覆盖默认的上传函数,接下来我们看一下使用http-request的方法来定义这个上传函数会出现什么问题?

   // 自定义上传函数,覆盖默认的上传
    uploadSectionFile(params) {
      console.log(params.file);
      console.log(file);
      this.fileName = file.name;
      // apcremiId 组件库id
      // version 版本号
      // file  压缩包
      this.impProgressPercent = true;
      let i = 1;
      let timer = setInterval(() => {  // 这只是一个动画效果可以忽略
        this.importProgressPercent = i;
        i++;
        if (i == 100) {
          clearInterval(timer);
        }
      }, 10);
      let formData = new FormData();  //定义传向服务器的参数
      formData.append("file", file.raw);
      formData.append("apcremiId", this.apcremiId);
      formData.append("version", this.version);
      formData.append("apcremiCode", this.apcremiCode);
      //接下来是接口请求 // 可以稍微看一下
      this.getRes(formData)
        .then((res) => {
          console.log(res);
          this.handleSuccess();
          let info = {
            packageUrl: res.url,
            packageName: res.packageNm,
            version: res.version,
            idList:res.idList
          };
          this.buildRes(info)
            .then((res) => {
              console.log(res);
              this.expProgressPercent = true;
              let j = 1;
              let timer1 = setInterval(() => {
                this.explainProgressPercent = j;
                j++;
                if (j == 100) {
                  clearInterval(timer1);
                  this.explainStart();
                }
              }, 40);
            })
            .catch((err) => {
              console.log(err);
              this.eError = err.errorMsg
              this.buildError();
            });
        })
        .catch((err) => {
          console.log(err);
          console.log("上传失败");
          this.iError = err.errorMsg
          this.handleError();
        });
    },

 3.出现的问题及总结

第一个问题:当传入组件包的时候发现上传文件传了两个接口,这个时候在后端有强校验的情况下,不能重复的传代码包,因为上传代码包解析之后就会入库,而入库的强校验就会抛出错误,前端项目接受后就会弹窗报错,体验极其不好,这个是我粗心的问题,还是得看文档看文档看文档,element-ui的upload组件有一个auto-upload属性默认为true,也就是默认在你选中文件的时候就会调用http-request这个函数,并且就会调用你自己配置的一个上传,导致上传两次报错

第二个问题:可以看出代码中一直链式调用,然后在promise的函数中写上传成功,上传失败和进度条的代码,而element-ui自己的上传成功等函数就会失效,我当时在想,这个可能是个缺陷,当然这个时候得感谢我的组长,一语点醒,当时他说:组件没有问题,你使用的有点问题,在源码中,upload组件内部往我们自定的上传方法中传递了一个options参数,其中包含了对upload上传文件 success 成功函数和error 失败函数,也就是说,其实我们也可以在自定义上传里面主动调用这些钩子以实现相应功能,当然这就是我自己使用的一个方法,可以算是误打误撞了,但是这个方法是有些繁琐。

如何解决这个问题其实非常简单,即添加return 语句返回promise 结果,因为我们大多数的请求都是使用axios,而axios返回的就是promise函数,所以只需要在你调用接口的地方去写一个return去返回他,就不用那么繁琐的去手动调用,有的时候判断多了,找不到自己的函数,让代码内部自己去判断,可以说是物尽其用。

之前的代码可以说减少了一半,阅读起来也看的清楚了,而那些成功或者失败触发相应的操作只需要在成功或者失败回调函数中定义就可以了 

 这是在网上找到的一个截图,可以发现我们可以通过http-request的自定义方法中的return promise来关联内部的成功,失败函数。

附言:

后端大哥处理导入文件的处理逻辑:

1.处理tgz格式的压缩包

2.获取文件流(MultipartFile file)

3.先上传服务器作为临时文件供解析使用(解析需要校验,需要上传才能解析)

4.判断指定目录下指定文件是否存在,存在的话就解析json格式文件,并返回jsonArray数组

5.将临时文件复制到指定目录(因为只能在指定目标目录下才能构建)

6.根据jsonArray的数据入库,返回构建的需要参数

7.根据所传参数构建vue组件(这里的vue组件就是一个页面)

加载全部内容

相关教程
猜你喜欢
用户评论