换个姿式上传?el-upload + qiniu-js 的实现

关于element-uiel-upload,实际上issue中提到的次数也很多,不少初试者可能 get 不到愉快使用的点,提了issue以后又大多由于规范问题直接被机器人过滤或者关闭。例如最近一次相关的issue是想寻求关于http-request的使用,但也由于规范问题被直接关闭。因此咱们就稍微作一个比较接地气的业务类分享。javascript

0. 咱们要什么?

这个问题就简单了:首先,咱们须要一个好看的皮囊!那Vue基本没得选了,element-uiel-upload很符合口味。其次,咱们须要一个有趣的灵魂,咱们是使用七牛的对象存储的,但咱们的想法是想使用qiniu-js这个官方的SDK。由于el-upload开放了请求方法的自定义,因此咱们改造一下。vue

1. 咱们怎么作?

qiniu-js SDK

直接就看文档了。java

实际上为何要直接用七牛的 SDK 而不是组件带的请求方法将就用一下就好呢?这里我有两点能够解释:稳定,懒。七牛放出来的东西确定更适合他们本身的服务,因此本身安排action啊或者data什么的可能会安排错,那还不如直接按照他们给出的方式来作就好了。好比分片,若是只是从使用角度来看,直接用SDK的话我就不用去关心到底要怎么分,要怎么上传,要怎么结合成一个文件。我只须要让后端把上传策略都作好放出一个token,剩下的就什么都不用作了。还有浏览器方面,既然跟Vue一块儿使用了,那么杂事webpack已经帮咱们处理了,咱们根本不用关心。webpack

好了关于安装和引入就跳过了,直接看方法如何调用。简单看它的上传是以观察者形式,经过qiniu.upload注册一个方法,经过该方法进行订阅即上传操做,取消订阅即取消上传操做。而观察者又会拆分出三个方法:next, error, complete,简单说就是管过程,错误以及完成状况。这部分能够直接依据文档写:git

const observable = qiniu.upload(file, key, token, putExtra, config)
const subscription = observable.subscribe(next, error, complete) // 上传开始

// subscription.unsubscribe() 这个方法能够取消操做
复制代码

next方法接收一个参数,这个参数包含各类上传进度信息:github

const next = ({ total }) => {
  // 
  const {
    loaded, // 已上传大小,单位为字节。
    total,  // 本次上传的总量控制信息,单位为字节
    percent // 当前上传进度,范围:0~100
  } = total
};
复制代码

因此若是你没有什么特殊需求的话,只须要percent能捕获进度就好了。web

complete接收一个参数,当上传完整以后,服务器按照配置给你返回的内容,具体显示什么都看本身的后端如何配置。ajax

error顾名思义就是当上传出现错误的时候作出处理,对错误的处理也是因人而异,直接看文档就行。element-ui

至此先保留,再看el-upload后端

el-upload

我建议是去瞟一眼el-upload源码,这样也方便理解,当一个文件拖入或添加到组件的时候,好看的皮囊和有趣的灵魂是如何协调工做的。若是只是想理解上传的方式,只看有出现ajax的两个文件就行:一个是ajax.js还有一个是upload.vue

若是你说:我不想看源码!而后又想能跟你写的请求方法结合,能够!有一个蠢方法:先定义一个方法接收一个参数,这个方法直接向uploadhttp-request进行绑定:

{
  template: `<el-upload :http-request="request" />`
  methods: {
    request(obj) { console.log(obj) }
  }
}
复制代码

至此你就能看到el-upload打包的全部请求信息的了,你就能够根据这个好看的皮囊设计灵魂了。(有一个issue提到关于headerdata的问题,实际上都会包含在这之中)

但我仍是建议能够看一下源码,由于你看了源码以后你就会发现一些细节等下能够用到,好比upload.vue133~143这几行代码:

onProgress: e => {
  this.onProgress(e, rawFile);
},
onSuccess: res => {
  this.onSuccess(res, rawFile);
  delete this.reqs[uid];
},
onError: err => {
  this.onError(err, rawFile);
  delete this.reqs[uid];
}
复制代码

而这个时候你就能会知道:噢!我等下能够利用到这个皮囊的进度条显示,成功以及失败的处理。并不须要本身再去引入更多的组件或者更多的回调操做。甚至若是之后再也不用“七牛”做为请求方法,组件也可复用不用修改。因此#8291就有点惋惜了,若是他还没找到方法的话但愿这篇文章能够帮到他。

3. merge

弄清楚以后,就是把他们“揉起来”。对于el-upload能用的信息咱们已经清楚,剩下的关于业务上的操做就移步element的官方文档便可。咱们来制造灵魂,在此以前注释一下:咱们团队是很是强调规范和拥抱classes + TypeScript这种方式的,但写这篇文章的人是比较喜欢直接用JavaScript,并且应该更多人须要的是后者因此本次产出的“渣代码”用JavaScript,那么:

// upload.js

// token 找后端,obj 这里指代从 el-upload 接收到的 object
export const upload = token => obj => {
  const { file } = obj 

  // 关于 key 要怎么处理自行解决,但若是为 undefined 或者 null 会使用上传后的 hash 做为 key.
  const key = "" 
  
  // 因人而异,自行解决
  const putExtra = {},
        config   = {} 

  const observable = qiniu.upload(file, key, token, putExtra, config)

  // 刚刚获得的信息可使用了,这样可使用到 el-upload 的进度条
  const next = ({ total }) => obj.onProgress({ percent: total.percent })

  const error = err => obj.onError(err)

  const complete = res => obj.onSuccess(res)

  const subscription = observable.subscribe(next, error, complete)
  return subscription // 返回以方便取消上传操做
}
复制代码
Vue.component('upload', {
  template: `<el-upload :http-request="request" />`
  methods: {
    request(obj) {
      // 你怎么搞到token我无论!
      const uploader = upload(token)
      const subscription = uploader(obj) 
    }
  }
})
复制代码

这是一个抛砖引玉的操做,大体上就只有这样了,剩下全靠爱和定制就完事儿了!

相关文章
相关标签/搜索