vue2封装上传图片组件ImageUpolad OSS上传

父组件引用

<el-form-item label="视频封面:" prop="img" class="top_10">
  <ImageUpolad v-model="videoUploadFrom.img" :imgType="['jpg', 'jpeg', 'png']" size="" @uploadEvt="uploadEvt" :disabled="typeVideo === '3'" />
</el-form-item>

import ImageUpolad from '@/components/imageUpolad'
components: { ImageUpolad },

// 图片 上传
uploadEvt(url) {
  this.videoUploadFrom.img = url
},

 子组件

<template>
  <div class="">
    <el-upload
      class="avatar-uploader"
      action="#"
      :show-file-list="false"
      :http-request="upLoaderFun"
      :before-upload="beforeAvatarUpload"
      accept=".jpg,.png,.gif,.jpeg,.JPG,.PNG,.GIF,.JPEG"
      :disabled="upload || disabled"
    >
      <div v-if="imageUrl" class="avatar">
        <i class="el-icon-error" @click="deleteEvt"></i>
        <img :src="imageUrl" class="avatars" />
      </div>
      <div v-else class="avatar-uploader-icon">
        <div class="icon_clone"></div>
        <span class="span_1">
          点击选择
          <span class="center1">本地文件</span>
          上传文件
        </span>
        <span class="span_2">支持 {{ uploadType }} 格式,{{ imageSize ? ` ${imageSize[0]}px*${imageSize[1]}px ,` : '' }}{{file_size}}以内</span>
      </div>
    </el-upload>
  </div>
</template>

<script>
import { uploadImg } from '@/utils/tool'
export default {
  name: 'ImageUpolad',
  props: {
    value: {
      type: String,
      default: ''
    },
    disabled: {
      type: Boolean,
      default: false
    },
    imgType: {
      typee: Array,
      default: () => {
        return ['jpg', 'png', 'jpeg']
      }
    },
    size: {
      type: String,
      default: ''
    },
    maxSize: {
      type: Number,
      default: 1024
    }
  },
  data() {
    return {
      uploadType: '',
      imageSize: '',
      imageUrl: this.value
    }
  },
  computed: {
    upload() {
      if (!this.imageUrl) return false
      return true
    },
    file_size() {
      if (this.maxSize >= 1024) {
        return (this.maxSize / 1024).toFixed(2) + 'MB'
      } else {
        return this.maxSize + 'KB' 
      }

    },
  },
  watch: {
    value(newV) {
      this.imageUrl = newV
    }
  },
  mounted() {
    this.uploadType = this.imgType.join('、')
    this.imageSize = this.size ? this.size.split('*') : ''
  },
  methods: {
    upLoaderFun({ file }) {
      uploadImg(file).then((res) => {
        if (res.code === 1) {
          this.$emit('uploadEvt', res.data)
        } else {
          this.$message.error('上传图片失败')
        }
      })
    },
    beforeAvatarUpload(file) {
      if (file.size / 1024 > this.maxSize) {
        this.$message.error(`请上传指定大小内的图片!`)
        return false
      }
      if (this.size) {
        const _this = this
        const isSize = new Promise((resolve, reject) => {
          // const width = 5120
          // const height = 2880
          const width = this.imageSize[0] - 0 // 限制图片尺寸
          const height = this.imageSize[1] - 0
          const _URL = window.URL || window.webkitURL
          const img = new Image()
          img.onload = () => {
            const valid = img.width === width && img.height === height
            valid ? resolve() : reject()
          }
          img.src = _URL.createObjectURL(file)
        }).then(
          () => {
            return file
          },
          () => {
            _this.$message.error('请上传标准格式宽高的图片')
            return Promise.reject()
          }
        )
        return isSize
      }
    },
    deleteEvt() {
      this.$emit('uploadEvt', '')
    }
  }
}
</script>

<style lang='scss' scoped>
/deep/.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
/deep/.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
/deep/.avatar-uploader-icon {
  font-size: 14px;
  width: 400px;
  height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px 0;
  justify-content: space-evenly;
  .icon_clone {
    display: block;
    width: 36px;
    height: 48px;
    border: 4px solid #cccccc;
  }
  .span_1 {
    color: #666666;
    .center1 {
      color: #409eff;
    }
  }
  .span_2 {
    font-size: 14px;
    color: #cccccf;
  }
}
/deep/.avatar {
  width: 400px;
  height: 200px;
  display: block;
  position: relative;
  .el-icon-error {
    display: none;
  }
  &:hover {
    .el-icon-error {
      display: block;
      position: absolute;
      right: 10px;
      top: 10px;
      font-size: 20px;
    }
  }
  .avatars {
    width: 400px;
    height: 200px;
  }
}
</style>

 OSS上传js


// OSS上传类型
const dataObjectType = [
  // 文件
  {
    // 有效类型
    validType(dataObject) {
      if (!(dataObject instanceof File)) return false;
      return true;
    },
    // 有效长度
    async validSize(dataObject, maxSize) {
      await vaildFileSize(dataObject, maxSize);
    },
    async upload(client, dataObject) {
      const [p, ...names] = dataObject.name.split(".").reverse();
      let file_name = `${names.reverse().join('.')}_w${new Date().getTime()}.${p}`;
      return await client.multipartUpload(file_name, dataObject, {})
    },
  },
  // blob
  {
    // 有效类型
    validType(dataObject) {
      if (!(dataObject instanceof Blob)) return false;
      return true;
    },
    // 有效长度
    async validSize(dataObject, maxSize) {
      await vaildFileSize(dataObject, maxSize);
    },
    async upload(client, dataObject, filetype) {
      return new Promise((res, rej) => {
        let file_name = `w${new Date().getTime()}.${filetype}`;
        const fileReader = new FileReader();
        fileReader.onload = (e) => {
          const buffer = new OSS.Buffer(e.target.result);
          res(client.put(file_name, buffer, {}));
        };
        fileReader.readAsArrayBuffer(dataObject);
      });
    },
  },
];

// 验证文件大小
export function vaildFileSize(obj, maxSize) {
  return new Promise((res, rej) => {
    // 限制大小
    if (maxSize >= 0 && maxSize < obj.size) {
      rej();
    } else {
      res();
    }
  });
}

export function uploadImg(file, options={}) {
  return UploadOSS(file, options)
    .then(({url, name}) => {
      return {
        code: 1,
        data: url,
      };
    })
}


export async function UploadOSS(dataObject, options={}) { 
  console.log('dataObject', dataObject, '---', options)
  const maxSize = options.maxSize || maxUploadFileSize;
  const overMaxSizeMsg = options.overMaxSizeMsg || `文件大小不能超过${formatDataSize(maxSize)}`
  let dataObjectT;
  if (!dataObjectType.some(item => item.validType(dataObject) ? dataObjectT = item : false)) throw new Error("数据类型错误");
  try {
    await dataObjectT.validSize(dataObject, maxSize)
  } catch (error) {
    if (!options.notWarning) {
      vue.$message.warning(overMaxSizeMsg);
      console.warn(error);
    }
    throw new Error(overMaxSizeMsg);
  }
  const results = await managerUpload(dataObject)
  console.log('results', results)
  sessionStorage.setItem('fileName', results.name)
  return results
}


export function managerUpload(file) {
  const protocol =  window.location.protocol
  var sendData = new FormData();
  sendData.append('appcode',sessionStorage.getItem('appcode'));
  sendData.append('v','manager');
  sendData.append('alias','manager_upload');
  sendData.append('file',file);
  sendData.append('admin_id',sessionStorage.getItem('admin_id'));
  sendData.append('key',sessionStorage.getItem('key'));
  return new Promise((resolve, reject) => {
    $.ajax({
      url: protocol + '//' + window.CONFIG.SERVICE_URL + '接口地址',
      type: 'post',
      data: sendData,
      //ajax2.0可以不用设置请求头,但是jq帮我们自动设置了,这样的话需要我们自己取消掉
      contentType:false,
      //取消帮我们格式化数据,是什么就是什么
      processData:false,
      success: function (res) {
        if (typeof res === 'string') {
          res = JSON.parse(res)
        }
        if (res.code === 1) {
          resolve(res.data[0])
        } else {
          reject(res)
          vue.$message.error(res.message);
        }
      },
      error: function (err) {
        console.log(err, 'errrr')
        vue.$message.error(err.message);
      }
    })
  })
}

// 格式化数据大小
export var formatDataSize = function(size) {
  const format = (num) => {
    if (num / parseInt(num) === 1) {
      return num;
    } else {
      const decimalLength = num.toString().split('.')[1].length;
      return num.toFixed(decimalLength > 3 ? 3 : decimalLength);
    }
  };
  if (size / 1024 / 1024 < 1) {
    return format(size / 1024) + 'KB';
  } else {
    return format(size / 1024 / 1024) + 'MB';
  }
};



    // 上传
    const {url, name} = await UploadOSS(file, {
      maxSize: _maxSize,
      overMaxSizeMsg: item.overMaxSizeMsg,
      filetype: options.filetype,
    });
export default {
  uploadImg,
  UploadOSS,
vaildFileSize
}

------------------------------------------------------分割线---------------------------------------------------------------

不封装简易版OSS图片上传

<el-form-item label="标签辅助icon:" prop="icon">
  <el-upload
    accept=".jpg,.jpeg,.png,.JPG,.JPEG,.PNG"
    class="ermUp"
    action="#"
    :http-request="upLoaderFun"
    :show-file-list="false"
  >
    <img v-if="addOrEditruleForm.icon" :src="addOrEditruleForm.icon" class="avatar">
    <i v-else class="el-icon-plus avatar-uploader-icon" />
  </el-upload>
    <div class="uploaderBtn_box">
      <p>请上传像素尺寸为60*60,格式为PNG的图片</p>
    </div>
</el-form-item>


// 上传icon
upLoaderFun(data) {
  this.$common.ossClient(data.file, 1).then(r => {
    if (r.res && r.res.statusCode === 200) {
      this.addOrEditruleForm.icon = r.res.requestUrls[0].split('?')[0]
    } else {
      console.log(r.message)
    }
  })
},
import { ossUpLoad } from '@/api/common.js'

// oss上传
async ossClient(file, size, handout) {
  const isLt2M = file.size / 1024 / 1024 < size
  let parms = {}
  if (isLt2M) {
    parms = await ossUpLoad()
  }
  return new Promise((resolve, reject) => {
    if (!isLt2M) {
      Notification.error({
        title: '出现错误',
        message: `发送数据大小不能超过${size}M!`,
        position: 'bottom-right'
      })
      resolve('error')
    }
    let filename = ''
    if (file.name) {
      filename = +new Date() + '/' + file.name
    } else {
      filename = 'xc-uploadfile/file_' + new Date().getTime() + '.' + 'mp3'
    }
    const client = new OSS({
      accessKeyId: parms.data.AccessKeyId,
      accessKeySecret: parms.data.AccessKeySecret,
      stsToken: parms.data.SecurityToken,
      secure: true,
      endpoint: process.env.VUE_APP_SCENE === 'MASTER' ? 'oss-cn-shanghai.aliyuncs.com' : process.env.VUE_APP_SCENE === 'DEV' ? 'oss-cn-hangzhou.aliyuncs.com' : 'oss-cn-hangzhou.aliyuncs.com',
      bucket: process.env.VUE_APP_SCENE === 'MASTER' ? handout !== '课程讲义' ? 'cxt-static-master' : 'cxt-auth-master' : process.env.VUE_APP_SCENE === 'DEV' ? handout !== '课程讲义' ? 'cxt-static-dev' : 'cxt-auth-dev' : handout !== '课程讲义' ? 'cxt-static-dev' : 'cxt-auth-dev'
    })
    async function putObject() {
      try {
        const result = await client.put(filename, file)
        console.log(result, '上传返回数据')
        resolve(result)
      } catch (e) {
        console.log(e, '报错222')
      }
    }
    putObject()
    if (parms.code === 1) {
    }
  })
},



//mian.js文件挂载公共js

import common from '@/util/common' // 公共方法定义
Vue.prototype.$common = common

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值