跟随Element学习Vue小技巧(20)——Upload

1,907 阅读5分钟

不相信自己的人

连努力的价值都没有

前言

那一秒,70万人接吻,50万人拥抱,20万人牵手,剩余的人在围观
想想那个场面,该是有多激动啊
如果不出意外的话,我依然在围观,可不巧的是,偏偏出了点小意外 最后,不得不躺在医院里围观 o(╥﹏╥)o

准备好了吗?上传,上船,跟紧咯,黑灯瞎火的,千万注意安全哦

1 Index

上传结构slot

昨天去超市购物,大大小小十几件,排了好长队,终于到我了
没想到,今天做活动,购物200可抽奖一次
幸运的是,我抽中了一等奖,(^▽^)

  • 先生,您是一个人吗?
  • 对呀,怎么了?
  • 不好意思,要两个人一起才可以
  • 为什么呀
  • 因为成双成兑
  • 好一个成双成对 o(╥﹏╥)o

无奈的我,拎着几袋东西伤心的回去了

代码片段

return (
  <div>
    { this.listType === 'picture-card' ? uploadList : ''}
    {
      this.$slots.trigger
        ? [uploadComponent, this.$slots.default]
        : uploadComponent
    }
    {this.$slots.tip}
    { this.listType !== 'picture-card' ? uploadList : ''}
  </div>
);

技巧解析

你有过买东西的经历吗?
零零碎碎的东西总得用袋子装起来吧
如果一次需要传递很多的props呢?
你最好也找个袋子slot装起来
发现没,整个upload有四个袋子给你
trigger,default,tip,file
props解决不了的,用slot解决

jsx语法slot

你知道哪些袋子呢?

  • 塑料袋
  • 手提袋
  • 皮带
  • 录像带
    。。。
    喂喂喂,别光顾着发呆!!!

代码片段

return (
  <div>
    ...
    {
      this.$slots.trigger
        ? [uploadComponent, this.$slots.default]
        : uploadComponent
    }
    {this.$slots.tip}
    ...
  </div>
);
if (this.showFileList) {
  uploadList = (
    <UploadList
      ...
      handlePreview={this.onPreview}>
      {
        (props) => {
          if (this.$scopedSlots.file) {
            return this.$scopedSlots.file({
              file: props.file
            });
          }
        }
      }
    </UploadList>
  );
}

技巧解析

slot又有哪些类型呢?
默认插槽,具名插槽,作用域插槽

1.默认插槽-我需要袋子

// upload.vue
<div>{this.$slots.default}</div>

2.默认插槽-给你一个袋子

// upload
<el-upload>
  <div>
    <h2>我是一个袋子,给你<h2>
    <p>我可以装很多东西哦</p>
  </div>
</el-upload>

3.具名插槽-我需要布袋子

// upload.vue
<div>{this.$slots.trigger}</div>

4.具名插槽-给你一个布袋子

// upload
<el-upload>
  <slot name="trigger">
    <h2>我是一个布袋子,给你<h2>
    <p>我同样可以装很多东西哦</p>
  </slot>
</el-upload>

5.作用域插槽-我需要袋子,袋子里面有惊喜喔 ^^

// upload.vue
<UploadList>
  {
    (props) => {
      if (this.$scopedSlots.file) {
        return this.$scopedSlots.file({
          file: props.file
        });
      }
    }
  }
</UploadList>

6.作用域插槽-给你一个袋子,哇,真的有惊喜,file,倍儿爽 **

<li
  v-for="file in files"
  ...
>
  <slot :file="file">
    <img
      ...
      :src="file.url" alt=""
    >
    ...
    <span>
      <span
        ...
        @click="handlePreview(file)"
      >
       ...
      </span>
    </span>
  </slot>
</li>

这里有一份完整的数据配置秘籍送给你

JSX深入数据对象 传送门

2 Upload

中断上传abort

  • 包租婆,包租婆,为什么突然之间没水了呢?

代码片段

 abort(file) {
  const { reqs } = this;
  if (file) {
    let uid = file;
    if (file.uid) uid = file.uid;
    if (reqs[uid]) {
      reqs[uid].abort();
    }
  }
}
 post(rawFile) {
  ...
  const options = {
    ...
    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];
    }
  };
  const req = this.httpRequest(options);
  this.reqs[uid] = req;
  ...
}
handleRemove(file, raw) {
  ...
  let doRemove = () => {
    this.abort(file);
    ...
    this.onRemove(file, fileList);
  };
  ...
}

技巧解析

你有过断电的体验吗?
是不是很酸爽 o(╥﹏╥)o
上传到一半,突然给停了???
动作别太快了,服务压力三大啊
快速点击时,需要及时制止,abort()
每次请求保存一份req,this.reqs[uid] = req
请求有结果了,无论成功与否,删除本次req,delete this.reqs[uid]
操作过程中,正在上传,及时制止

Axios取消请求 传送门

3 ajax

formData

  • 你对生活有什么要求?
  • 我一个月拿3000块钱,快餐随便吃,饮料随便喝,想去哪就去哪,自在得很
  • 你对对象有什么要求呢?
  • 我的对象起码月入5万,你知道我很挑剔的,顿顿得有肉,喝酒喝茅台,还得全国各地旅游,如果养不起我,免谈
  • 你对对象的要求还挺高的
  • 那必须的

代码片段

if (option.data) {
  Object.keys(option.data).forEach(key => {
    formData.append(keyoption.data[key]);
  });
}

formData.append(option.filename, option.file, option.file.name);

技巧解析

你对对象的要求高吗?
反正upload对对象要求挺高的
不是formData不处
下次出门前,是不是得先照照镜子

FormData对象的使用 传送门

只要有想见的人 就不再是孤身一人了

参考链接

往期回顾