vue ali-oss 视频文件上传下载封装组件

转载 https://blog.csdn.net/cxz792116/article/details/96906166

创建vue项目,并安装ali-oss

npm install ali-oss  --save  或者 cnpm install ali-oss  --save 

1.单文件上传 下载简易示例代码如下:(只能单次上传,点击刷新页面会清除缓存,无法保存文件下载地址)

单文件效果图,上传时会有进度条动画
在这里插入图片描述

<template>
  <div>
    <el-upload
      class="avatar-uploader"
      action=""
      :http-request="beginUpload"
      :show-file-list="false">
      <img v-if="imageUrl" :src="imageUrl" class="avatar">
      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
    </el-upload>
    <el-progress :percentage="Number(percentage.toFixed(2))"></el-progress>
    <el-button @click="pauseUpload">暂停</el-button>
    <el-button @click="goonUpload">继续</el-button>
    <el-button @click="download">下载</el-button>
  </div>
</template>

<script>
import OSS from 'ali-oss'
//定义全局变量,保存文件下载地址
var upurl = ''
export default {
  components: {},
  data () {
    return {
      imageUrl: '',
      percentage: 0,
      checkpoint: null,
      client: null,
      filename: '',
      upurl: '',
    }
  },
  computed: {
  },
  created () {
    this.client = new OSS({
      region: 'oss-cn-hangzhou',
      accessKeyId: '<Your AccessKeyId>',
      accessKeySecret: '<Your AccessKeySecret>',
      bucket: 'Your bucket name',
      secure: false
    })
  },
  methods: {
   //下载文件
  	download() {
  	//实现跳转到新的url,而不是在当前的地址后面追加url
		 window.location.href = upurl;
     },
    async ossUpload (filename, file) {
      let _this = this
      try {
        let result = await _this.client.multipartUpload(filename, file, {
          progress: async function (p, checkpoint) {
            _this.checkpoint = checkpoint
            _this.percentage = p * 100
          },
          checkpoint: _this.checkpoint
        })
        console.log(result)
      } catch (e) {
        console.log(e)
      }
    },
    beginUpload (file) {
      let _this = this
      let filename = file.file.name
      filename = filename.split('.')[0] + '_' + new Date().getTime() + '.' + filename.split('.')[1]
      _this.file = file
      _this.filename = filename
      _this.ossUpload(filename, file.file)
      //保存上传的文件下载地址
     upurl = this.client.signatureUrl(_this.filename);
    },
    pauseUpload () {
      this.client.cancel()
    },
    goonUpload () {
      let file = this.file
      let _this = this
      _this.ossUpload(_this.filename, file.file)
    }
  }
}
</script>

2.多文件、多类型,异步上传(暂未封装完整)(只设置了能多次上传视频,其他类型的文件无法上传,需要重新设置判断条件)

效果图
在这里插入图片描述

<template>
  <div id="upload-cp">
    <a href="javascript:;" class="file">选择文件
     <input type="file" :multiple="multiple" :accept="acceptType" id="uploadFile" @change="getFile($event)" />
    </a>
    <p v-if="isCount">选择了<span>{{file.length}}</span>个文件</p>
    <el-button class="uploadBtn" :disabled="disabled" @click="upload" type="primary">上传</el-button>
  </div>
</template>

<script>
/* eslint-disable */
import OSS from "ali-oss"
export default {
  name: "Upload",
  props:{
   // 是否支持多文件上传
   multiple:{
    type: Boolean,
    default: true
   },
   // 文件上传的个数限制
   limitCount:{
    type: Number,
    default: 1,
   },
   // 文件上传的接受的类型  video/* :视频类型, image/*:图片,根据需要判断
   acceptType:{
    type: String,
    default: 'video/*',
   },
   // 存放到 阿里云oss 对应的文件  video:视频, image: 图片, adjunct: 附件
   storeType:{
    type: String,
    default: 'video',
   }
  },
  data () {
    return {
      client: null,
      loading: null,
      file: null,
      isCount: false,
      disabled: false,
      minW: 5,             // 视频最小宽度
      maxW: 1000000,       // 视频最大宽度
      minH: 5,             // 视频最小长度      
      maxH: 100000,        // 视频最大长度
      minSize: 0.1,        // 视频文件最大值
      maxSize: 5000,       // 视频文件最小值
      minDurate: 0.1,      // 视频时长最小值
      maxDurate: 1000,     // 视频时长最大值
      fileInfo: [],     // 上传oss成功后的返回值
      videoLists: [],   // 创建视频
      videoSize: [],    // 视频大小
      videoRatio: [],   // 视频分辨率
      videoDurate: [],  // 视频时长
    }
  },
  created () {
   	this.client = new OSS({
      region: 'oss-cn-hangzhou',
      accessKeyId: '<Your AccessKeyId>',
      accessKeySecret: '<Your AccessKeySecret>',
      bucket: 'Your bucket name',
      secure: false
    })
  },
  mounted () {},
  methods: {
    // 开始动画
    startLoading () {
      this.loading = this.$loading({
        lock: true,
        text: '上传中...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
    },
    // 结束动画
    endLoading(){
      this.loading.close()
    },
    // 获取文件路径
    getObjectURL (file) {
      let url = null
      if (window.createObjcectURL != undefined) {
        url = window.createOjcectURL(file)
      } else if (window.URL != undefined) {
        url = window.URL.createObjectURL(file)
      } else if (window.webkitURL != undefined) {
        url = window.webkitURL.createObjectURL(file)
      }
      return url
    },
    // 选择文件
    getFile (event) {
      this.disabled = false
      this.file = event.target.files
      for(let i = 0; i < this.file.length; i++){
        let video = document.createElement('video')
        video.setAttribute('controls', 'controls')
        video.setAttribute('src', this.getObjectURL(this.file[i]))
        this.videoLists.push(video)
        this.videoSize.push(this.file[i].size / 1024 / 1024)
      }
      this.isCount = true
    },
    // 随机
    random_string(len) {
        len = len || 32;
        let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz12345678', maxPos = chars.length, pwd = '';
        for (let i = 0; i < len; i++) {
            pwd += chars.charAt(Math.floor(Math.random() * maxPos));
        }
        return pwd;
    },
    // 日期
    getDate(){
      const date = new Date()
      let year = date.getFullYear()
      let month = date.getMonth() > 9 ? date.getMonth() + 1 : `0${date.getMonth() + 1}`
      let day = date.getDate() > 9 ? date.getDate() : `0${date.getDate()}`
      return `${this.storeType}/${year}${month}${day}/`
    },
    // 上传
    upload () {
      if(!this.file) return this.$message.error('请上传文件')
      if(this.limitCount != this.file.length) return this.$message.error(`请上传${this.limitCount}个文件`)
	// 这样需要根据 上传文件的类型进行再一次的封装,因为我这是以视频上传为主。后续进行完善
      this.videoLists.map(item => {
        this.videoDurate.push(item.duration)
        this.videoRatio.push({h:item.videoHeight,w:item.videoWidth})
      })
      // 判断视频大小
      let sizeBolean = this.videoSize.find((item) => {
        return item < this.minSize || item > this.maxSize
      })
      // 判断视频时长
      let durationBolean = this.videoDurate.find((item) => {
          return  item < this.minDurate || item > this.maxDurate
      })
      // 判断视频分辨率
      let raidoBolean = this.videoRatio.find((item) => {
         return item.w < this.minW || item.w > this.maxW
         if(this.minW < item.w && item.w > this.maxW) {
           return item.h < this.minH || item.w > this.maxH
         } 
      })
      if(sizeBolean) return this.$message.error('视频只能上传0.5M ~ 50M')
      if(durationBolean) return this.$message.error('视频时长只能上传1 ~ 10分钟')
      if(raidoBolean) return  this.$message.error('视频分辨率不合适')  
      this.disabled = true    
      this.submitFile()

    },
    // 提交到oss服务器
    submitFile(){
      this.startLoading()
      const len = this.file.length 
      let uploadLength = 0
      for (let i = 0; i < len; i++) {
        let file = this.file[i];
        let headerInfo = this.random_string(6) + '_' + new Date().getTime() + '.' + file.name.split('.').pop();
        let storeAs = this.getDate() + headerInfo
        this.client.multipartUpload(storeAs, file, {
        // 特别说明,这个地方需要设置,不然视频无法用浏览器的方式下载,只能播放。
          headers: { 'Content-Disposition': headerInfo }
       }).then((res) => {
         uploadLength++
         if (uploadLength === len) {
            this.endLoading()
            this.$message({message: `您成功上传了${len}文件`,type: 'success'});
            // 上传成功的后得到阿里云 文件路径, 回调保存到自己服务器中,为下载或者在线播放做下一步操作
            this.$emit('uploadDone', this.fileInfo);
         }
         this.fileInfo.push(res.name)
       }).catch((err) => {
          this.endLoading()
          this.$message.error('网络错误,请稍后再试试!')
          console.log(err);
       });
      }
    }
  }
};
</script>

<style lang="scss" scoped>
#upload-cp{
  display: flex;
  flex-direction: row;
  align-items: center;
  .file {
    position: relative;
    display: inline-block;
    background: #D0EEFF;
    border: 1px solid #99D3F5;
    border-radius: 4px;
    padding: 0px 12px;
    overflow: hidden;
    color: #1E88C7;
    text-decoration: none;
    text-indent: 0;
    font-size: 16px;
  }
  .file input {
    position: absolute;
    font-size: 16px;
    right: 0;
    top: 0;
    opacity: 0;
    height: 40px;
  }
  .file:hover {
    background: #AADFFD;
    border-color: #78C3F3;
    color: #004974;
    text-decoration: none;
  }
  p{
    font-size: 14px;
    margin-left: 10px;
    span{
      color:red;
    }
  }
  .uploadBtn{
    margin-left: 50px;
  }
}
</style>


说明:因为采用的是原生的input type=file方式,进而对样式进行了优化。可根据自己需要进行调整。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ali-oss阿里云提供的 OSS(Object Storage Service)的 JavaScript SDK,可以在浏览器端和 Node.js 环境下使用。Vue.js 是一个流行的前端框架,常用于开发单页面应用程序。 在 Vue.js 中使用 ali-oss 可以方便地上传和下载文件阿里云 OSS。下面是 ali-oss 的依赖详解: 1. 安装 ali-ossVue.js 中使用 ali-oss 需要先安装它。可以使用 npm 安装: ``` npm install ali-oss --save ``` 2. 引入 ali-ossVue.js 中使用 ali-oss 需要先引入它。可以在 Vue 组件中使用 import 引入: ``` import OSS from 'ali-oss' ``` 3. 创建 OSS 实例 在使用 ali-oss 之前,需要先创建一个 OSS 实例。可以使用以下代码创建: ``` const client = new OSS({ region: '<your region>', accessKeyId: '<your accessKeyId>', accessKeySecret: '<your accessKeySecret>', bucket: '<your bucket>' }) ``` 其中,region 是 OSS 存储所在的区域,accessKeyId 和 accessKeySecret 是阿里云账号的 AccessKey,bucket 是要操作的存储桶名称。 4. 上传文件 使用 ali-oss 可以方便地上传文件OSS。可以使用以下代码上传文件: ``` const result = await client.put('object-key', 'local-file'); ``` 其中,object-key 是上传到 OSS文件路径,local-file 是本地文件路径。 5. 下载文件 使用 ali-oss 可以方便地下载文件到本地。可以使用以下代码下载文件: ``` const result = await client.get('object-key', 'local-file'); ``` 其中,object-key 是 OSS 中的文件路径,local-file 是本地文件路径。 总的来说,ali-oss 可以方便地在 Vue.js 中上传和下载文件阿里云 OSS。在使用 ali-oss 时,需要先安装并引入它,然后创建一个 OSS 实例,最后使用 put() 或 get() 方法上传或下载文件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值