广告
返回顶部
首页 > 资讯 > 精选 >Vue如何实现封装一个切片上传组件
  • 115
分享到

Vue如何实现封装一个切片上传组件

2023-07-05 12:07:59 115人浏览 独家记忆
摘要

今天小编给大家分享一下Vue如何实现封装一个切片上传组件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。组件效果单文件切片上传

今天小编给大家分享一下Vue如何实现封装一个切片上传组件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

    组件效果

    单文件切片上传

    Vue如何实现封装一个切片上传组件

    多文件切片上传

    Vue如何实现封装一个切片上传组件

    组件使用案例

    <template>  <div id="app">    <div class="upload-wrap">      <UploadSlice        :action="uploadInfoSlice.actionChunk"        :headers="uploadInfoSlice.headers"        :limit="uploadInfoSlice.limit"        :accept="uploadInfoSlice.accept"        :show-file-list="false"        cancelable        :on-success="handleSuccess"        :on-remove="handleRemove"        :on-cancel="handleCancel"        :on-upload-pre="handleUploadPre"        :on-upload-merge="handleUploadMerge"        :on-fORM-data="genFormData"      />    </div>  </div></template><script>import UploadSlice from './components/UploadSlice.vue'import { uploadPre, uploadMerge } from '@/api/upload-slice'export default {  name: 'App',  components: {    UploadSlice  },  data() {    return {      // 上传部分      uploadInfoSlice: {        actionChunk: process.env.VUE_APP_BASE_API + '/storage/file/v3/chunk', // 切片请求上传路径        headers: { 'Authorization': 'Bearer XXX' }      }    }  },  methods: {    // 分片预请求    async handleUploadPre(file) {      const form = new FormData()      form.append('fileSource', 'APPLICATION')      form.append('originFileName', file.name)      let res = ''      try {        res = await uploadPre(form)      } catch (error) {        throw new Error(error)      }    },    // 构造分片参数    genFormData(chunks, uid) {      const prepareId = this.getCurrentPrepareId(uid)      return chunks.map(chunk => {        const form = new FormData()        form.append('chunk', chunk.file)        form.append('uploadId', prepareId)        form.append('partNumber', chunk.index)        return form      })    },    // 合并请求    async handleUploadMerge(file, uid) {      const prepareId = this.getCurrentPrepareId(uid)      const form = new FormData()      form.append('fileSource', 'APPLICATION')      form.append('hash', prepareId)      form.append('filename', file.name)      // return 建议使用, 用于handleSuccess获取数据      try {        const res = await uploadMerge(form)        return res      } catch (error) {        return error      }    },    // 判断当前处理prepareId    getCurrentPrepareId(uid) {      for (const item of this.progressFileList) {        if (item.uid === uid) {          return item.prepareId        }      }    }  }}</script>

    使用文档

    Attribute

    标红色部分为二次封装处理过的功能,其他为el-upload自带属性

    参数说明类型可选值默认值备注
    action必选参数,分片上传的地址,预请求和合并请求在组件外操作String--
    headers设置上传的请求头部String--
    multiple是否支持多选文件boolean-

    accept可上传文件类型,多种类型用","分隔 (格式不符合自动提示)String--
    on-remove文件列表移除文件时的钩子function(file, fileList)&mdash;&mdash;
    on-success文件上传成功时的钩子function(response, file, fileList)&mdash;&mdash;
    on-error文件上传失败时的钩子function(err, file, fileList)&mdash;&mdash;
    on-progress文件上传时的钩子function(event, file, fileList)&mdash;&mdash;
    on-change文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用function(file, fileList)&mdash;&mdash;
    on-exceed文件超出个数限制时的钩子function(files, fileList)&mdash;&mdash;
    list-type文件列表的类型stringtext/picture/picture-cardtext
    show-file-list是否显示已上传文件列表(文件分片上传时建议设置false,否则会有两个进度条)boolean&mdash;true
    file-list上传的文件列表, 例如: [{name: 'food.jpg', url: 'xxx.cdn.com/xxx.jpg'}]array&mdash;[]
    disabled是否禁用boolean&mdash;false
    cancelable是否支持取消boolean&mdash;false
    limit最多允许上传个数(超出个数自动提示)number&mdash;&mdash;
    size限制大小String&mdash;&mdash;
    hideBtn是否在上传过程中隐藏上传按钮boolean&mdash;&mdash;false

    Slot

    插槽名说明
    trigger触发文件选择框的内容
    tip提示说明文字
    more-tips在默认提示后补充说明

    封装过程

    切片上传组件是基于el-upload进行的二次封装,文章开头组件效果演示可以看到上传一个文件会发送三个请求:prepare,chunk, merge,也就是整个上传过程,主要分为三步:1.预请求 2.分片请求 3.合并请求,预请求和合并请求就是我们正常的Http请求,主要处理的是分片请求,分片请求主要的步骤是:

    • 将文件切片

    • 构造切片请求参数

    • 控制分片请求的并发

    1. 文件切片

    el-upload上传后, 在on-change属性的回调里可以获取文件file,通过file.raw.slice对文件进行切片,目前的切片规则是:1.小于10M 固定一片 2.小于50M 文件10%为一片 3.大于50M 固定5M 一片(可以根据自己的需求进行修改)

    genFileChunks(file) {  const chunks = []  let cur = 0  // 小于10M 固定一片  if (file.size < (10 * 1024 * 1024)) {    chunks.push({      index: cur,      file: file.raw.slice(cur, file.size),      originFilename: file.name    })    return chunks  }  // 小于50M 文件10%为一片  if (file.size < (50 * 1024 * 1024)) {    const chunkSize = parseInt(file.size * 0.1)    while (cur < file.size) {      chunks.push({        index: cur,        file: file.raw.slice(cur, cur + chunkSize),        originFilename: file.name      })      cur += chunkSize    }    return chunks  }  // 大于50M 固定5M 一片  const chunkSize = parseInt(5 * 1024 * 1024)  while (cur < file.size) {    chunks.push({      index: cur,      file: file.raw.slice(cur, cur + chunkSize),      originFilename: file.name    })    cur += chunkSize  }  return chunks},

    一个32M的文件按照10%切一片,构造好的切片数据是这样的

    Vue如何实现封装一个切片上传组件

    2. 构造切片请求参数

    切片请求不同业务的参数是变化的,所以参数部分可以抛出给父组件处理,增加组件的复用性

    父组件

    <template>  <UploadSlice    :action="uploadInfoSlice.actionChunk"    :headers="uploadInfoSlice.headers"    :on-form-data="genFormData"  /></template><script>  methods: {    // 构造分片参数    genFormData(chunks, uid) {      const prepareId = this.getCurrentPrepareId(uid)      return chunks.map(chunk => {        const form = new FormData()        form.append('chunk', chunk.file)        form.append('uploadId', prepareId)        form.append('partNumber', chunk.index)        return form      })    },  },</script>

    子组件

    <template>  <el-upload      action=""      :accept="accept"  ></template><script>  props: {    onFormData: {      type: Function,      default: () => {}    },  },  methods: {    async uploadChunks(uid) {      // 预请求      // ---------------      // 上传切片      const requests = this._genRequest(this._genUploadData(uid), uid)      // 控制并发      await this.sendRequest(requests)            // 合并请求      // ---------------    },        // 构造分片参数    _genUploadData(uid) {      const chunks = this.getCurrentChunks(uid)      return this.onFormData(chunks, uid)    },        // 生成调用请求:[Promise, Promise]    _genRequest(uploadData, uid) {      console.log('uploadData', uploadData)      const file = this.getCurrentFile(uid)      const chunks = this.getCurrentChunks(uid)      return uploadData.map((form, index) => {        const options = {          headers: this.$attrs.headers,          file: file,          data: form,          action: this.action,          onProgress: progress => {            chunks[index].progress = Number(              ((progress.loaded / progress.total) * 100).toFixed(2)            )            this.handleProgress(progress, file, uid)          }        }        return options      })    },  },</script>

    3. 控制分片请求的并发

    切片上传如果不控制并发,在分片很多时,就会同时发送很多个http请求,导致线程阻塞,影响页面其他请求的操作,所以控制并发是需要的。我设置的是最多允许3个并发请求。

        sendRequest(requests, limit = 3) {      return new Promise((resolve, reject) => {        const len = requests.length        let counter = 0        let isTips = false // 只提示一次失败        let isStop = false // 如果一个片段失败超过三次 认为当前网洛有问题 停止全部上传        const startRequest = async() => {          if (isStop) return          const task = requests.shift()          if (task && task.file.status !== 'cancel') {            // 利用try...catch捕获错误            try {              // 具体的接口  抽离出去了              await ajax(task)              if (counter === len - 1) { // 最后一个任务                resolve()              } else { // 否则接着执行                counter++                startRequest() // 启动下一个任务              }            } catch (error) {              // 网络异常              if (error === 'NETWORK_ERROR' && !isTips) {                Message.error('网络异常,文件上传失败')                this.upLoading = false                this.preLoading = false                isTips = true                this.handleRemove('', [])              }              // 接口报错重试,限制为3次              if (task.error < 3) {                task.error++                requests.unshift(task)                startRequest()              } else {                isStop = true                reject(error)              }            }          }        }        // 启动任务        while (limit > 0) {          // 模拟不同大小启动          setTimeout(() => {            startRequest()          }, Math.random() * 2000)          limit--        }      })    }  }

    以上就是“Vue如何实现封装一个切片上传组件”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

    --结束END--

    本文标题: Vue如何实现封装一个切片上传组件

    本文链接: https://www.lsjlt.com/news/351851.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Vue实现封装一个切片上传组件
      目录组件效果使用文档封装过程1. 文件切片2. 构造切片请求参数3. 控制分片请求的并发完整代码待完善组件效果 单文件切片上传 多文件切片上传 组件使用案例 <templa...
      99+
      2023-03-19
      Vue封装切片上传组件 Vue切片上传组件 Vue切片上传
    • Vue如何实现封装一个切片上传组件
      今天小编给大家分享一下Vue如何实现封装一个切片上传组件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。组件效果单文件切片上传...
      99+
      2023-07-05
    • vue-upload-component如何封装一个图片上传组件
      这篇文章主要介绍了vue-upload-component如何封装一个图片上传组件,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。需求分析业务...
      99+
      2022-10-19
    • vue-cropper插件如何实现图片截取上传组件封装
      小编给大家分享一下vue-cropper插件如何实现图片截取上传组件封装,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!需求场景:后台开发需要上传图片并进行相应比例尺寸图片的截取,本组件开发采用Ant Design Vue组...
      99+
      2023-06-15
    • vue-cropper插件实现图片截取上传组件封装
      基于vue-cropper插件实现图片截取上传组件封装的具体代码,供大家参考,具体内容如下 需求场景: 后台开发需要上传图片并进行相应比例尺寸图片的截取,本组件开发采用Ant Des...
      99+
      2022-11-12
    • vue-cropper组件如何实现图片切割上传
      小编给大家分享一下vue-cropper组件如何实现图片切割上传,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!vue-cropper在vue中的引入1、组件内引入...
      99+
      2023-06-15
    • vue-cropper组件实现图片切割上传
      本文实例为大家分享了vue-cropper组件实现图片切割上传的具体代码,供大家参考,具体内容如下 这几日,等来了些空闲,用vue和spring boot实践一次头像上传,因此记下...
      99+
      2022-11-12
    • vue如何实现文件切片上传
      这篇文章主要介绍了vue如何实现文件切片上传的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇vue如何实现文件切片上传文章都会有所收获,下面我们一起来看看吧。在实际开发项目过程中有时候需要上传比较大的文件,然后呢...
      99+
      2023-07-05
    • vue中怎么实现一个上传图片组件
      本篇文章给大家分享的是有关vue中怎么实现一个上传图片组件,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1.首先得有一个[type=file]...
      99+
      2022-10-19
    • Vue中图片上传组件封装-antd的a-upload二次封装的实例
      目录图片上传组件封装-antd的a-upload二次封装api组件封装使用优化图片上传组件封装-antd的a-upload二次封装 a-upload组件 api const pub...
      99+
      2022-11-13
    • vue如何实现上传图片组件
      这篇文章给大家分享的是有关vue如何实现上传图片组件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。未上传状态上传状态其他状态(查看/删除)自定义组件文件名称 - 这里叫UploadImg.vue<templ...
      99+
      2023-06-25
    • 如何开发一个封装iframe的vue组件
      这篇文章给大家分享的是有关如何开发一个封装iframe的vue组件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。VUE的基本组成单元,我看应该是组件。用VUE开发前端项目,就是开发一个个组件,然后搭积木一样,将项...
      99+
      2023-06-14
    • 基于Vue实现封装一个虚拟列表组件
      目录组件效果属性插槽封装过程滚动条正常显示加载渲染大量数据不卡顿能对列表数据进行操作增删等完整代码待完善正常情况下,我们对于数据都会分页加载,最近项目中确实遇到了不能分页的场景,如果...
      99+
      2023-03-07
      Vue封装虚拟列表组件 Vue 虚拟列表组件 Vue 虚拟列表
    • vue如何实现上传组件
      这篇文章主要介绍vue如何实现上传组件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!思路文件上传的两种实现方式From形式<form   method="post&quo...
      99+
      2023-06-15
    • 基于Vue如何封装一个虚拟列表组件
      今天小编给大家分享一下基于Vue如何封装一个虚拟列表组件的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。组件效果使用方法<...
      99+
      2023-07-05
    • vue3.0 移动端二次封装van-uploader实现上传图片(vant组件库)
      1、前提:业务需求,最多上传6张图片,并可以实现本地预览 2、解决方法:使用vant组件库中的van-uploader实现 3、代码实现 template <div cl...
      99+
      2022-11-13
    • vue如何实现上传图片文件
      这篇文章给大家分享的是有关vue如何实现上传图片文件的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。原始input标签form表单上传<input type="file"&nbs...
      99+
      2023-06-15
    • js自己实现一个大文件切片上传+断点续传的示例代码
      目录首先我们来分析一下需求一、 格式校验二、 文件切片三、 断点续传 + 秒传 + 上传进度PM:喂,那个切图仔,我这里有个100G的视频要上传,你帮我做一个上传后台,下班前给我哦,...
      99+
      2022-11-13
    • 深析如何封装一个vue自定义日历组件
      执行这个方法之后,此时calendarProps的值为:4、根据日历属性生成日历日期的数据当我们已经知道本月第一天对应的周几索引值、本月一共有多少天和上个月一共有多少天这三个核心数据之后,就可以开始生成对应的日历数据了。思路如下:由于大部分...
      99+
      2023-05-14
      Vue.js 数据可视化 前端
    • 如何使用vue封装一个自定义日历组件
      本文小编为大家详细介绍“如何使用vue封装一个自定义日历组件”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何使用vue封装一个自定义日历组件”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。核心代码实现1、梳理思...
      99+
      2023-07-05
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作