vue项目中上传视频和图片到阿里云oss方法

第一步,封装js文件在util文件下:

// fileUpload.js
import axios from 'axios'
let basePath  = 'xxx.xxx.xx' // 你的服务器接口域名
/**
 * @description: 文件附件上传
 * file: 文件raw对象
 * successCallback: 成功的回调函数
 * errCallBack: 错误的回调函数
 * progressCallback: 上传进度的回调函数
 * dir: 上传阿里云目标文件夹 eg:图片image,视频video等
 */
const upload = function(file, successCallback = new Function(), errCallBack = new Function(), progressCallback = new Function(), dir = 'image') {
  let fileName = file.name
  axios({
    method: 'get',
    url: "www.wwww.www" // 请求签名接口,找后台要
  })
    .then(res => {
    // 拿到签名信息后,组装表单数据,作参考,具体的字段找后台要
      let obj = res.data
      let config = {}
      config.host = obj['host']
      config.policyBase64 = obj['policy']
      config.accessid = obj['accessid']
      config.signature = obj['signature']
      config.expire = parseInt(obj['expire'])
      config.callbackbody = obj['callback']
      config.dir = obj['dir']
      let fd = new FormData(),
      key = config.dir + fileName  //文件名
      fd.append('key', key)
      fd.append('success_action_status', '200')
      fd.append('x-oss-object-acl', 'public-read')
      fd.append('x-oss-meta-fullname', fileName)
      fd.append('OSSAccessKeyId', config.accessid)
      fd.append('policy', config.policyBase64)
      fd.append('signature', config.signature)
      fd.append('success_action_status', '200')
      fd.append('file', file)
      if (config.host.indexOf('http:') > -1) {
        var protocol = window.location.protocol || 'http:'
        var subUrl = config.host.substring(5, config.host.length)
        config.host = protocol + subUrl
      }
      // 数据组装完成后,发送上传请求到阿里云oss
      axios({
        url: config.host,
        method: 'POST',
        data: fd,
        processData: false,
        cache: false,
        contentType: false,
        // 这里,我们可以做上传经度
        onUploadProgress: function(progressEvent) {
          if (progressEvent.lengthComputable) {
            let percent = (progressEvent.loaded / progressEvent.total) * 100 || 0
            progressCallback({
              percent: percent
            })
          }
        }
      })
        .then(() => {
        // 拿到结果后,做其他操作
          let size = file.size > 1000000 ? parseFloat(file.size / 1000000).toFixed(2) + 'M' : parseFloat(file.size / 1000).toFixed(2) + 'KB'
          successCallback({
            attachment: fileName,
            aliyunAddress: key,
            size: size,
            host: config.host
          })
        })
        .catch(err => {
          errCallBack(err)
        })
    })
    .catch(err => {
      errCallBack(err)
    })
}
export default upload

第二部,将el-upload的组件结合封装

<template>
<div class="text-msg-pic-upload flex-start">
    <div v-if="Filetype=='video'">
      <video v-for="i in tempFileList" :key="i.uid" :src="i.url" width="96" height="96" class="video" @click="handlePictureCardPreview_video(i)"></video>
    </div>
    <el-upload
      :class="{ display: uploadDisabled }"
      list-type="picture-card"
      ref="upload"
      action
      multiple
      :http-request="handleUpload"
      :auto-upload="autoUpload"
      :limit="limit"
      :file-list="tempFileList"
      :on-exceed="handleExceed"
      :on-success="handleSuccess"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      :before-upload="beforeUpload"
      :on-preview="handlePictureCardPreview"
      :show-file-list="Filetype=='image'"
      accept="jpg,.jpeg,.png,.JPG,.JPEG,.mp4,.wmv,.rmvb,.mov,.avi,.flv"
    >
      <i class="el-icon-plus"></i>
      <div slot="tip" class="el-upload__tip" v-if="tipsFlag">{{ tips }}</div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible" append-to-body @close="closeDialog">
      <img width="100%" :src="dialogImageUrl" alt="" />
    </el-dialog>
    <el-dialog :visible.sync="dialogVisible_video" append-to-body @close="closeDialog">
      <video width="100%" :src="dialogVideoUrl" controls/>
    </el-dialog>
  </div>
</template>

<script>
import upload from '@/utils/fileUpload.js'
export default {
//   name: 'UploadImageDemo',
  props: {
    width: {
      type: String,
      default: '240px'
    },
    Filetype: {
      type: String,
      default: 'image'
    },
    size: {
      type: String,
      default: 50
    },
    autoUpload: {
      type: Boolean,
      default: true
    },
    limit: {
      type: Number,
      default: 3
    },
    limitType: {
      type: Array,
      default: () => ['image/jpeg', 'image/png', 'image/jpg']
    },
    disabled: {
      type: Boolean,
      default: false
    },
    imgList: {
      type: Array,
      default: () => []
    },
    tipsFlag: {
      type: Boolean,
      default: false
    },
    tips: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      // 上传文件列表,el-upload使用,临时保存数据。
      tempFileList: this.imgList,
      host: '', // 阿里云上传服务器地址根路径
      uploadDisabled: false,
      dialogImageUrl: '',
      dialogVisible: false,
      dialogVisible_video:false,
      dialogVideoUrl:'',
    }
  },
  watch: {
    // 解决第二渲染接口, 图片还保留着原来的问题 JerryYi
    imgList: {
      immediate: true,
      handler(val) {
        this.tempFileList = val
      }
    }
  },
  computed: {
    upText() {
      return this.autoUpload ? '上传文件' : '选择文件'
    }
  },
  created() {
  },
  mounted() {},
  methods: {
    handlePictureCardPreview_video(file) {
      this.dialogVideoUrl = file.url
      this.dialogVisible_video = true
    },
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },
    closeDialog(){
      this.dialogVideoUrl = ''
      this.dialogImageUrl = ''
      this.dialogVisible_video = false
      this.dialogVisible = false
    },
    beforeUpload(file) {
      let types = this.limitType
      const isImage = types.includes(file.type)
      const isLt20M = file.size / 1024 / 1024 <  parseInt(this.size)
      if (!isImage) {
        if(this.Filetype=='video'){
          this.$message({
            message: types.length == 0 ? '只能上传视频格式!' : '上传视频只能是 mp4、wmv、rmvb、mov、avi、flv 格式!',
            type: 'warning'
          })
          return false
        }
        this.$message({
          message: types.length == 0 ? '上传图片只能是 PNG 格式!' : '上传图片只能是 JPG、PNG 格式!',
          type: 'warning'
        })
        return false
      }
      if (!isLt20M) {
        this.$message.error('上传图片大小不能超过 '+parseInt(this.size)/10+'MB!')
        return false
      }
      return isImage && isLt20M
    },
    // 自定义上传操作
    handleUpload(op) {
      let dir = `images`
       upload(
        op.file,
         res => {
          let temp = {
            name: res.attachment,
            url: res.host + '/' + res.aliyunAddress
           }
          this.host = res.host
          op.onSuccess(temp)
         },
        err => {
          console.log(err)
         },
        res => {
          op.onProgress(res)
         },
         dir
       )
    },
    // 上传成功后触发
    handleSuccess(response, file, fileList) {
      this.filterFileFn(fileList)
    },
    // 返回给接口要用的格式
    filterFileFn(fileList) {
      let filterArr = fileList
        .filter(item => !item.status || item.status !== 'ready') // 过滤未上传的文件
        .map(item => {
          let url = item.response ? item.response.url : item.url
          return {
            url: url, // item.url || item.response.url
            name: item.name
          }
        })
      // console.log('fileList', fileList)
      this.$emit('onSuccessFiles', filterArr)
    },
    // 监听移除文件列表
    handleRemove(file, fileList) {
      if (file.status === 'success') {
        this.filterFileFn(fileList)
      }
    },
    handleExceed(files, fileList) {
      this.$message({ message: `当前限制选择 ${this.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`, type: 'warning' })
    },
    beforeRemove() {
      // return this.$confirm(`确定移除 ${file.name}?`)
    }
  }
}
</script>

<style>
.text-msg-pic-upload .el-upload--picture-card,
.text-msg-pic-upload .el-upload-list--picture-card .el-upload-list__item {
  width: 96px;
  height: 96px;
  line-height: 106px;
}
.display .el-upload--picture-card {
  display: none;
}
.text-msg-pic-upload .video{
  background-color: #fff;
  cursor: pointer;
  margin-right: 8px;
}
</style>

第三步,需要的地方就行引用

<template>
<--上传图片-->
<uploadImage :limit="5" :imgList="fileImgList" @onSuccessFiles="onSuccessImgFiles"  />
<--上传视频-->
    <uploadImage :limit="1" :imgList="fileImgList" @onSuccessFiles="onSuccessImgFiles" :limitType="limitType" size='200' Filetype='video' />
</template>

<script>
import uploadImage from './components/uploadImage'
export default {
  components: {
    uploadImage,
  },
  data () {
    return {
      fileImgList: [], //图片列表,
      limitType:[
        "video/mp4",
        "video/ogg",
        "video/flv",
        "video/avi",
        "video/wmv",
        "video/rmvb",
        "video/mov"]
    }
  },
  methods: {
    // 监听图片上传
    onSuccessImgFiles(files) {
      console.log('onSuccessImgFiles', files)
      this.fileImgList = files
    },
}
</script>

<style lang="scss">
@import "@/assets/scss/settings/feedback.scss";
</style>

可以看下详细:https://blog.csdn.net/qq_42991509/article/details/122967392

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值