Vue2.0利用vue-resource上传文件到七牛的实例代码


Posted in Javascript onJuly 28, 2017

本文介绍了Vue2.0利用vue-resource上传文件到七牛,分享给大家,希望对大家有帮助

关于上传,总是有很多可以说道的。

16年底,公司项目番茄表单的前端部分,开始了从传统的jquery到vue 2.0的彻底重构。但是上传部分,无论是之前的传统版本,还是Vue新版本,都是在使用着FileAPI这款优秀的开源库,只是进行了简单的directive化。为什么呢?因为兼容性。没办法,公司项目不等同于个人项目,必须要考虑大多数浏览器。否则,上传部分完全可以利用Vue-Resource以及FormData来抛开对FileAPI的依赖。这让我深感遗憾,幸好这个简单的遗憾在个人博客Vue化重构的时候得以弥补。

上传流程

Vue2.0利用vue-resource上传文件到七牛的实例代码

图不重要看文字

input[type="file"] change事件触发后,先去(如果是图片,可以同时通过FileReader以及readAsDataURL将图片预览在页面上)后台请求七牛的上传token,将拿到的token和key以及通过change传递过来的files一起append到formData中。然后将formData通过post传递给七牛,七牛在处理后将返回真正的文件地址

获取token

const qiniu = require('qiniu')
const crypto = require('crypto')
const Config = require('qiniu-config')

exports.token = function*() {
  //构建一个保存文件名
  //这里没有处理文件后缀,需要自己传递过来,然后在这里处理加在key上,非必须
  const key = crypto.createHash('md5').update(((new Date()) * 1 + Math.floor(Math.random() * 10).toString())).digest('hex')
  //Config 七牛的秘钥等配置
  const [ACCESS_KEY, SECRET_KEY, BUCKET] = [Config.accessKey, Config.secretKey, Config.bucket] 
  qiniu.conf.ACCESS_KEY = ACCESS_KEY
  qiniu.conf.SECRET_KEY = SECRET_KEY
  const upToken = new qiniu.rs.PutPolicy(BUCKET + ":" + key)
  try {
    const token = upToken.token()
    return this.body = {
      key: key,
      token: token
    }
  } catch (e) {
    // throw error
  }
}

//假设api 地址是 /api/token

上传组件 upload.vue

<template>
  <label class="mo-upload">
    <input type="file" :accept="accepts" @change="upload">
    <slot></slot>
  </label>
</template>
<style lang="scss">
  .mo-upload {
    display: inline-block;
    position: relative;
    margin-bottom: 0;
    input[type="file"] {
      display: none;
    }
    .mo-upload--label {
      display: inline-block;
      position: relative;
    }
  }
</style>
<script>
  export default {
    name : 'MoUpload',
    props : {
      accepts : { //允许的上传类型
        type : String,
        default : 'image/jpeg,image/jpg,image/png,image/gif'
      },
      flag : [String, Number], //当前上传标识,以便于在同一个监听函数中区分不同的上传域
      maxSize : {
        type : Number,
        default : 0 //上传大小限制
      }, 
    },
    methods: {
      upload (event) {
        let file = event.target.files[0]
        const self = this
        const flag = this.flag
        if (file) {
          if (this.maxSize) {
            //todo filter file
          }
          //filter file, 文件大小,类型等过滤
          //如果是图片文件
          // const reader = new FileReader()
          // const imageUrl = reader.readAsDataURL(file)
          // img.src = imageUrl //在预览区域插入图片

          const formData = new FormData()
          formData.append('file', file)
          
          //获取token
          this.$http.get(`/api/token/`)
          .then(response => {
            const result = response.body
            formData.append('token', result.token)
            formData.append('key', result.key)
            //提交给七牛处理
            self.$http.post('https://up.qbox.me/', formData, {
              progress(event) {
                //传递给父组件的progress方法
                self.$emit('progress', parseFloat(event.loaded / event.total * 100), flag) 
              }
            })
            .then(response => {
              const result = response.body
              if (result.hash && result.key) {
                //传递给父组件的complete方法
                self.$emit('complete', 200 , result, flag)
                //让当前target可以重新选择
                event.target.value = null
              } else {
                self.$emit('complete', 500, result, flag)
              }
            }, error => self.$emit('complete', 500, error.message), flag)
          })
        }
      }
    }
  }
</script>

父组件调用

<template>
  <section>
    ...
    <figure class="upload-preview">
      <img :src="thumbnail" v-if="thumbnail"/>
    </figure>
    <mo-upload flag="'thumbnail'" @complete="uploadComplete" @progress="uploadProgress">
      <a>选择图片文件<i class="progress" :style="{width:progress + '%'}"></i></a>
    </mo-upload>
    ...
  </section>
</template>
<script>
  import MoUpload from 'upload'
  export default {
    components : {
      MoUpload,
    },
    data () {
      return {
        thumbnail : null,
        progress : 0 //上传进度
      }
    },
    methods : {
      uploadProgress (progress, flag) {
        //这里可以通过回调的flag对不同上传域做处理
        this.progress = progress < 100 ? progress : 0;
      },
      uploadComplete(status, result, flag) {
        if (status == 200) { //
          this.thumbnail = `domain.com/${result.key}` //七牛域名 + 返回的key 组成文件url
        } else {
          //失败处理
        }
      },
    }
  }
</script>

小结

相比于FILEApi 或者其他上传组件,这种方法代码量最小。但是缺点也是显而易见的,大量html5 API的使用,势必会回到兼容性这个老大难上来,慎重的选择性使用吧‘

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 模式设计之工厂模式学习心得
Apr 27 Javascript
关于js datetime的那点事
Nov 15 Javascript
浅析javascript中的DOM
Mar 01 Javascript
JS实现仿Windows经典风格的选项卡Tab切换代码
Oct 20 Javascript
jQuery ajax时间差导致的变量赋值问题分析
Jan 22 Javascript
Bootstrap组件之下拉菜单,多级菜单及按钮布局方法实例
May 25 Javascript
Vue.js基础指令实例讲解(各种数据绑定、表单渲染大总结)
Jul 03 Javascript
Vue2 配置 Axios api 接口调用文件的方法
Nov 13 Javascript
详解Vue取消eslint语法限制
Aug 04 Javascript
Javascript异步执行不按顺序解决方案
Apr 30 Javascript
three.js 如何制作魔方
Jul 31 Javascript
Element-ui 自带的两种远程搜索(模糊查询)用法讲解
Jan 29 Javascript
vue使用vue-cli快速创建工程
Jul 28 #Javascript
用JS实现简单的登录验证功能
Jul 28 #Javascript
基于JavaScript实现图片连播和联级菜单实例代码
Jul 28 #Javascript
vue中七牛插件使用的实例代码
Jul 28 #Javascript
Vue.js中的图片引用路径的方式
Jul 28 #Javascript
将 vue 生成的 js 上传到七牛的实例
Jul 28 #Javascript
详解Vue2中组件间通信的解决全方案
Jul 28 #Javascript
You might like
PHP脚本的10个技巧(3)
2006/10/09 PHP
php若干单维数组遍历方法的比较
2011/09/20 PHP
flexigrid 参数说明
2010/11/23 Javascript
AJAX 网页保留浏览器前进后退等功能
2011/02/12 Javascript
javascript中类的定义及其方式(《javascript高级程序设计》学习笔记)
2011/07/04 Javascript
js+jquery实现图片裁剪功能
2015/01/02 Javascript
javascript字符串函数汇总
2015/12/06 Javascript
JavaScript lodash常见用法系列小结
2016/08/24 Javascript
js实现文本上下来回滚动
2017/02/03 Javascript
JavaScript模拟实现封装的三种方式及写法区别
2017/10/27 Javascript
nodejs实现解析xml字符串为对象的方法示例
2018/03/14 NodeJs
详解iframe跨域的几种常用方法(小结)
2019/04/29 Javascript
VueCli4项目配置反向代理proxy的方法步骤
2020/05/17 Javascript
[09:23]国际邀请赛采访专栏:iG战队VK,Tongfu战队Cu
2013/08/05 DOTA
python在指定目录下查找gif文件的方法
2015/05/04 Python
详解Python中的array数组模块相关使用
2016/07/05 Python
python实现简单聊天应用 python群聊和点对点均实现
2017/09/14 Python
python实现淘宝秒杀聚划算抢购自动提醒源码
2020/06/23 Python
linux下python使用sendmail发送邮件
2018/05/22 Python
Python代码一键转Jar包及Java调用Python新姿势
2020/03/10 Python
为什么是 Python -m
2020/06/19 Python
css3边框_动力节点Java学院整理
2017/07/11 HTML / CSS
钉钉企业内部H5微应用开发详解
2020/05/12 HTML / CSS
活动志愿者自荐信
2014/01/27 职场文书
计算机专业自荐信范文
2014/05/28 职场文书
2014年财务个人工作总结
2014/12/08 职场文书
五四青年节比赛演讲稿
2015/03/18 职场文书
56句经典英文座右铭
2019/08/09 职场文书
个人职业生涯规划之自我评估篇
2019/09/03 职场文书
励志语录:只有自己足够强大,才能不被别人践踏
2020/01/09 职场文书
详解Go与PHP的语法对比
2021/05/29 PHP
在Spring-Boot中如何使用@Value注解注入集合类
2021/08/02 Java/Android
Mysql存储过程、触发器、事件调度器使用入门指南
2022/01/22 MySQL
Vue.js中v-bind指令的用法介绍
2022/03/13 Vue.js
Java 中的 Lambda List 转 Map 的多种方法详解
2022/07/07 Java/Android
面试官问我Mysql的存储引擎了解多少
2022/08/05 MySQL