elementui upload 文件上传组件封装,预览、删除、下载、上传格式、超出限制隐藏上传、阿里oss自定义上传。

本文介绍了如何创建一个Vue组件FileUpload,该组件支持阿里云OSS的图片上传功能,包括文件大小限制、格式限制、上传前验证、上传进度显示、删除、预览和下载等操作。组件还提供了自定义上传接口,以便于对接不同的文件上传服务。在实际使用中,可以设置上传地址、文件大小限制、接受的文件类型以及上传数量限制等属性。
摘要由CSDN通过智能技术生成

1、新建组件FileUpload.vue

<template>
  <div>
    <el-upload
      :action="action"
      :file-list="fileList"
      list-type="picture-card"
      :http-request="uploadHttp"
      :headers="headers"
      :limit="limit"
      :accept="accept"
      :class="hideUpload || uploading ? 'hideUpload' : ''"
      :on-error="handleError"
      :before-upload="beforeUpload"
      :on-success="handleSuccess"
    >
      <i slot="default" class="el-icon-plus"></i>
      <div slot="file" slot-scope="{ file }">
        <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
        <span
          v-if="file.status === 'success'"
          class="el-upload-list__item-actions"
        >
          <span
            v-if="preview"
            class="el-upload-list__item-preview"
            @click="handleImgPreview(file)"
          >
            <i class="el-icon-zoom-in"></i>
          </span>
          <span
            v-if="download"
            class="el-upload-list__item-delete"
            @click="handleDownload(file)"
          >
            <i class="el-icon-download"></i>
          </span>
          <span
            v-if="deleted"
            class="el-upload-list__item-delete"
            @click="handleRemove(file)"
          >
            <i class="el-icon-delete"></i>
          </span>
        </span>
        <span
          v-else
          :class="[
            uploading ? 'uploading' : '',
            'el-upload-list__item-actions',
          ]"
        >
          <i class="el-icon-loading" /><i style="font-size: 14px">上传中</i>
        </span>
      </div>
    </el-upload>
    <el-dialog :visible.sync="previewVisible">
      <img width="100%" :src="previewImgUrl" alt="" />
    </el-dialog>
  </div>
</template>

<script>
import OSS from 'ali-oss'
export default {
  name: 'FileUpload',
  model: {
    prop: 'list',
    event: 'change',
  },
  props: {
    // 上传的地址
    action: {
      type: String,
      default: '#',
    },
    // 文件列表默认值, 格式[url1, url2]
    list: {
      type: Array,
      default: () => [],
    },
    // 设置上传的请求头部
    headers: {
      type: Object,
      default: () => {
        return {}
      },
    },
    // 上传文件大小限制, 默认0 不限制,单位M
    size: {
      type: [Number, String],
      default: 0,
    },
    // 文件上传格式, 默认jpeg, png,jpg
    accept: {
      type: String,
      default: 'image/jpeg,image/png',
    },
    // 是否显示删除操作按钮
    deleted: {
      type: Boolean,
      default: true,
    },
    // 是否显示预览操作按钮
    preview: {
      type: Boolean,
      default: true,
    },
    // 是否显示下载操作按钮
    download: {
      type: Boolean,
      default: true,
    },
    // 上传文件个数限制,默认0 不限制
    limit: {
      type: [Number, String],
      default: 0,
    },
  },
  data() {
    return {
      fileList: [], // 默认文件列表
      hideUpload: false, // 超出限制掩藏上传按钮
      uploading: false, // 是否上传中,上传时隐藏上传按钮
      previewImgUrl: '', // 预览图片地址
      previewVisible: false, // 是否显示预览
    }
  },
  mounted() {
    const { list } = this
    this.fileList = list.map((url) => {
      return { url }
    })
    this.handleChange()
  },
  methods: {
    // 自定义上传接口,如阿里oss, 不使用去掉最上面的 http-request
    uploadHttp({ file }) {
      // 后台sts方式 获取临时上传参数region, accessKeyId, accessKeySecret, stsToken, bucket
      const { region, accessKeyId, accessKeySecret, stsToken, bucket } = {} // 后台请求
      const client = new OSS({
        region,
        accessKeyId,
        accessKeySecret,
        stsToken,
        bucket,
      })
      const path = `image/${Date.now()/${file.name}}` // 定义上传路径, 上传路径=文件夹路径+文件名称
      client
        .put(path, file)
        .then(({ name }) => {
          const { fileList } = this
          const url = `http://${bucket}.${region}.aliyuncs.com/${name}`
          this.fileList = fileList.push({ url })
          this.handleChange()
        })
        .catch((e) => {
          this.$message.error('上传失败!')
          this.handleChange()
        })
    },
    // 上传前文件大小判断
    beforeUpload(file) {
      const { size } = this
      const overSize = size > 0 && file.size < 1024 * 1024 * size
      if (!overSize) this.$message.error(`上传文件大小不能超过 ${size}MB!`)
      this.uploading = overSize // 是否上传中
      return overSize
    },
    // 上传出错返回
    handleError(event, file, fileList) {
      console.log(event, file, fileList, 'error')
      this.$message.error('服务出错,上传失败!')
      this.handleChange()
    },
    // 默认上传接口成功返回
    handleSuccess(res, file, list) {
      // 根据res上传接口返回结果判断是否上传成功
      //注意size为1时 直接赋值 成功 this.fileList =[{url: url地址}] 失败 this.fileList = []                
      //上传大于1的下面处理方式
      // 上传失败处理
      // this.fileList = list.splice(fileList.length - 1, 1)
      // this.$message.error('上传失败!')
      // // 上传成功处理, 注意list数组返回值最后一个对象为本地上传的url地址,不是线上地址
      this.fileList.push({url: 上传成功返回的url地址})
      this.handleChange()
    },
    // 删除图片
    handleRemove(file) {
      const { fileList } = this
      this.fileList = fileList.filter((item) => item.uid !== file.uid)
      this.handleChange()
    },
    // 图片预览
    handleImgPreview(file) {
      this.previewImgUrl = file.url
      this.previewVisible = true
    },
    handleChange(file, list) {
      const { limit, fileList } = this
      if (limit > 0 && fileList.length >= limit) this.hideUpload = true
      else this.hideUpload = false
      this.uploading = false
      const fileArr = []
      fileList.forEach((item) => fileArr.push(item.url))
      console.log(fileArr)
      this.$emit('change', fileArr)
    },
    handleDownload(file) {
      const a = document.createElement('a')
      a.href = file.url
      a.click() // 模拟点击事件,实现图片文件的同源下载
    },
  },
}
</script>

<style>
.hideUpload .el-upload--picture-card {
  display: none;
}
.el-upload-list--picture-card .uploading.el-upload-list__item-actions {
  opacity: 1;
}
/*添加、删除文件时去掉动画过渡*/
.el-upload-list__item {
  transition: none !important;
}
</style>

2、使用

   <FileUpload
      v-model="fileList"
      action="#"
      :size="size"
      :accept="accept"
      :limit="limit"
    />


import FileUpload from '@/components/FileUpload'
export default {
  components: { FileUpload },
  data() {
    return {
      fileList: [],
      limit: 2,
      size: 2,
      accept: 'image/jpeg,image/png',
    }
  },
}

3、效果

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少十步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值