iView + 七牛云 上传组件封装

本贴最后更新于 1892 天前,其中的信息可能已经时移世易

新建一个页面模板

<!--
  搞什么事的: 七牛云组件的封装,接口获取token(地址什么的都是在后端写好返回在token里了)
  用法:vue组件
  params:
    acceptType(0,对应data里fileTypes数组的下标)
    :refid="'myfile'" (一个页面使用多个组件,用ref标示来区分)
    @next (向父组件传回调的next对象获取的参数)
    @complete (上传完成后返回对象(hash, key(七牛云路径))到父组件)
    @error (方法错误回调返回对象)

-->
<template>
  <div>
    <div class="buttonDiv">
      <Button
        icon="ios-cloud-upload-outline"
        @click="zh_uploadFile"
      >选择文件</Button>
      <input type="file" :ref="refid" @change="zh_uploadFile_change" style="display:none">
    </div>
<!--    进度条-->
    <div :ref="refid + 'ivu-progress'" class="ivu-progress ivu-progress-normal ivu-progress-show-info" style="display: none;max-width: 350px;">
      <div class="ivu-progress-outer">
        <div class="ivu-progress-inner">
          <div class="ivu-progress-bg" :ref="refid + 'ivu-progress-bg'" style="height: 2px"></div>
          <div class="ivu-progress-success-bg" :ref="refid + 'ivu-progress-success-bg'" style="width: 0%; height: 2px;"></div>
        </div>
      </div>
      <span class="ivu-progress-text">
        <span class="ivu-progress-text-inner" :ref="refid + 'ivu-progress-text-inner'"></span>
      </span>
    </div>
  </div>
</template>

<style lang="less">
  .buttonDiv {
    display: inline-block;
  }
  .progress {
    width: 400px;
    height: 2px;
  }
</style>

<script>
    import * as qiniu from 'qiniu-js'
    import getQnyToken from "../../assets/script/qiniuyun/getQnyToken";

    export default {
        name : 'qiNiuYun',
        props : {
            styles: Object,//样式
            refid:{//绑定的id
                type : String,
                default : ''
            },
            uploadType:{//上传类型 0:要素表    1:个人身份文件上传   2:证据文件上传
                type : String,
                default : ''
            },
            acceptType: {
                default: 0
            },
            path: ''  // 上传到七牛云到路径
        },
        data(){
            return {
                totalSize:0,//总量
                loaded:0,//已上传文件大小
                totalTime:0,//总用时/s
                speed:0,//当前速度
                lestTime:0,//剩余时间
                timmer:'',//定时器
                fileTypes: [
                    ['.jpg', '.png', '.jpeg', '.txt', '.xls', '.xlsx', '.doc', '.docx', '.word', '.pdf', '.ppt', '.pptx', '.wordx'],  // 对应上传文件类型 acceptType = 0
                ]
            }
        },
        methods: {
            //选择上传文件
            zh_uploadFile(){
                this.$refs[this.refid].click();
            },

            //选择文件后触发的事件
            zh_uploadFile_change(evfile){
                let typeFlag = false
                const that=this
                const file = evfile.target.files[0] //Blob 对象,上传的文件
                if (file) {
                    const fileTypes = this.fileTypes[this.acceptType]
                    const fileend = file.name.substring(file.name.lastIndexOf('.'))
                    for (let t of fileTypes) {
                        if (t === fileend) {
                            typeFlag = true
                            break
                        }
                    }
                } else {
                    this.$Message.error('取消上传!')
                    return false
                }
                if (typeFlag) {
                    //后端获取七牛token(//这里替换成给自己后端的token获取接口)
                    getQnyToken().then(res=>{
                        const uptoken = res
                        this.totalSize=file.size;
                        const key = this.path + this.getuuid()+'-'+file.name // 上传后文件资源名以设置的 key 为主,如果 key 为 null 或者 undefined,则文件资源名会以 hash 值作为资源名。
                        let config = {
                            useCdnDomain: true,   //表示是否使用 cdn 加速域名,为布尔值,true 表示使用,默认为 false。
                            region: qiniu.region.z2,     // 根据具体提示修改上传地区,当为 null 或 undefined 时,自动分析上传域名区域
                            concurrentRequestLimit: 7, //分片上传的并发请求量,number,默认为3
                        };

                        let putExtra = {
                            fname: "",  //文件原文件名
                            params: {}, //用来放置自定义变量
                            mimeType: null  //用来限制上传文件类型,为 null 时表示不对文件类型限制;限制类型放到数组里: ["image/png", "image/jpeg", "image/gif"]
                        };
                        this.observable = qiniu.upload(file, key, uptoken, putExtra, config)
                        //定时器用来统计上传时间
                        this.timmer=setInterval(() => {
                            //计时
                            that.totalTime+=1
                            //每秒统计一次速度(已上传大小/总耗时)
                            that.speed=that.loaded/that.totalTime
                            //计算剩余时间(总大小-已上传大小)/当前速度
                            that.lestTime=(that.totalSize-that.loaded)/that.speed
                        }, 1000);
                        this.subscription=this.observable.subscribe({
                            next: (result) => {
                                that.loaded=result.total.loaded
                                that.$emit('next',result,parseInt(this.lestTime)) // 可用来做进度条处理
                                // 百分比
                                let percent = result.total.percent.toFixed(0)
                                this.$refs[this.refid + 'ivu-progress'].style.display = 'block'
                                this.$refs[this.refid + 'ivu-progress-bg'].style.width = percent + '%'
                                this.$refs[this.refid + 'ivu-progress-text-inner'].innerHTML = percent + '%'
                                if (percent == '100') {
                                    this.$refs[this.refid + 'ivu-progress'].style.display = 'none'
                                }
                                // 主要用来展示进度
                                // this.$Notice.info({
                                //     title: "上传中,请稍后....",
                                //     duration: 0,
                                //     render: h => {
                                //         return h('span', [
                                //             h('div', {
                                //                 style: {
                                //                     color: "red",
                                //                 },
                                //             }, `上传过程请勿关闭浏览器或执行其他操作!`),
                                //             h('div', `进度${this.flieProgress}%,预计剩余${this.leastTime}`),
                                //         ])
                                //     }
                                // })
                            },
                            error: (errResult) => {
                                that.$emit('error',errResult)
                            },
                            complete: (result) => {
                                window.clearInterval(this.timmer)//清除计时
                                result.fileName = file.name
                                that.$emit('complete',result)
                            }
                        })
                        //清除文本值方便下次触发change
                        // this.$refs[this.refid].value = null
                    })
                } else {
                    this.$Message.error('指定文件格式错误,请重新上传')
                }
            },
            cancelUpload(){//取消上传
                window.clearInterval(this.timmer)//清除计时
                this.subscription.unsubscribe() // 上传取消
            },
            getuuid() {
                let s = []
                let hexDigits = "0123456789abcdef"
                for (let i = 0; i < 36; i++) {
                    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
                }
                s[14] = "4"  // bits 12-15 of the time_hi_and_version field to 0010
                s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
                s[8] = s[13] = s[18] = s[23] = "-"

                let uuid = s.join("")
                return uuid
            },
            quotePercent(num, total) {
                num = parseFloat(num);
                total = parseFloat(total)
                if (isNaN(num) || isNaN(total)) {
                    return '-'
                }
                return total <= 0 ? '0%' : (Math.round(num / total * 100) / 100.00)*100 + '%'
            },
            delFile(ref) {
                debugger
                this.$refs[ref].value = null
            }
        }
    }
</script>

创建一个 getQnyToken 文件,来获取七牛云的上传 token

import Axios from 'axios'

let api = process.env.baseUrl
let member_token
export default async function () {
  let store = $nuxt.$store
  // let route = $nuxt.$route
  if (process.browser) {
    member_token = JSON.parse(localStorage.getItem('memberToken'))
    // if (store.state.)
    let _token
    await Axios.get(api + '/api/qiniu/token/file?member_token=' + member_token)
      .then(res => {
        if (res.data.data) {
          _token = res.data.data.token
        }
      })
    return _token
  }
}

其他组件内调用:

<qi-niu-yun
                :acceptType=0
                :refid="'releaseTaskId'"
                :path="qnySaveUrl"
                v-show="qnyCallBackParam.documentName === null"
                ref="upload"
                @next="fileNext(arguments)"
                @complete="fileComplete"
                @error="fileError"/>

传入参数 acceptType 的值对应子组件(也就是封装的七牛云上传组件)里面 filleTypes 数组里面的下标

Props:

参数 说明 备注 类型
acceptType 对应子组件(也就是封装的七牛云上传组件)里面 filleTypes 数组里面的下标 int
refid 对应子组件的 ref,唯一性 如果一个页面有多个上传按钮,那么每个 refid 的值必须唯一 String
path 七牛云的上传路径 String

Callback Events:

事件名 说明 返回类型
@next 向父组件传回调的 next 对象获取的参数 Obj
@complete 上传完成后返回对象(hash, key(七牛云路径))到父组件 Obj
@error 方法错误回调返回对象 Obj
  • iView
    5 引用
  • 七牛云

    七牛云是国内领先的企业级公有云服务商,致力于打造以数据为核心的场景化 PaaS 服务。围绕富媒体场景,七牛先后推出了对象存储,融合 CDN 加速,数据通用处理,内容反垃圾服务,以及直播云服务等。

    29 引用 • 230 回帖 • 122 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    268 引用 • 666 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 378 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 185 关注
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 662 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖 • 2 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖 • 1 关注
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    373 引用 • 1858 回帖 • 1 关注
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖 • 2 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    133 引用 • 796 回帖
  • FFmpeg

    FFmpeg 是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。

    23 引用 • 32 回帖 • 7 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 522 关注
  • OneDrive
    2 引用 • 3 关注
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 610 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    108 引用 • 153 回帖 • 1 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 2 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖 • 2 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 369 关注
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 680 关注
  • Follow
    4 引用 • 12 回帖 • 4 关注
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    440 引用 • 1238 回帖 • 595 关注
  • ngrok

    ngrok 是一个反向代理,通过在公共的端点和本地运行的 Web 服务器之间建立一个安全的通道。

    7 引用 • 63 回帖 • 655 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    89 引用 • 150 回帖 • 1 关注
  • 书籍

    宋真宗赵恒曾经说过:“书中自有黄金屋,书中自有颜如玉。”

    83 引用 • 412 回帖
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 52 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖 • 2 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    7 引用 • 69 回帖 • 8 关注
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 624 关注