vue中使用element的upload实现文件上传给后端

<template>
  <div>
    <el-upload
      class="upload-demo"
      action=""
      :accept="accept"
      :http-request="uploadFile"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-progress="handleProgress"
      :on-exceed="handleExceed"
      :before-upload="beforeUpload"
      :limit="limit"
      :on-preview="handlePreview"
      :show-file-list="false"
    >
      <el-button
        size="small"
        type="success"
        plain
      >附件</el-button>
    </el-upload>
    <!-- <el-image ref="preview" style="display: none;" :src="url" :preview-src-list="[url]" /> -->
  </div>
</template>

<script>
import { uploadFile } from '@/api/file' // 文件上传接口
import { getFileURL } from '@/utils/file' // 获取文件地址接口
export default {
  props: {
    multiple: { // 是否支持多选文件
      type: Boolean,
      default: false
    },
    limit: {
      type: Number,
      default: 9
    },
    agencyId: {
      type: [Number, String],
      default: ''
    },
    accept: { // .zip,.txt
      type: String,
      default: ''
    },
    size: {
      type: Number,
      default: 10
    },
    fileType: {
      type: Array,
      default: () => [
        'pdf', 'doc', 'docx', 'xls', 'xlsx', 'txt', 'png', 'jpg', 'bmp', 'jpeg'
      ]
    },
    data: { // 上传时附带的额外参数
      type: Object,
      default: () => {} // return {id: 1}
    },
    name: { // 上传的文件字段名
      type: String,
      default: 'file'
    },
    // listType: { // 文件列表的类型 text/picture/picture-card
    //   type: String,
    //   default: 'text'
    // },
    list: { // 上传的文件列表, 例如: [{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}]
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      fileList: [],
      url: ''
    }
  },
  watch: {
    list: {
      handler(newV) {
        this.assembleFileList(newV)
      },
      deep: true
    }
  },
  mounted() {
    this.assembleFileList(this.list)
  },
  methods: {
    /**
     * 组装文件列表
     * @param {*} fileArr
     */
    async assembleFileList(fileArr) {
      const file = JSON.parse(JSON.stringify(fileArr))
      const newFileList = []
      for (let index = 0; index < file.length; index++) {
        newFileList.push({
          name: file[index]?.name,
          size: file[index]?.size || '',
          url: await getFileURL(file[index].url),
          status: file[index]?.status || 'success',
          saveUrl: file[index].url
        })
      }
      this.fileList = newFileList
    },
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择${this.limit}个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`)
    },
    /**
     * 上传之前的回调
     * @param {*} file
     */
    beforeUpload(file) {
      if (file.type !== '' || file.type !== null || file.type !== undefined) {
        // 截取文件的后缀,判断文件类型
        const FileExt = file.name.replace(/.+\./, '').toLowerCase()
        // 计算文件的大小
        const isLt5M = file.size / 1024 / 1024 < this.size // 这里做文件大小限制
        // 如果大于50M
        if (!isLt5M) {
          this.$message.error('上传文件大小不能超过 50MB!')
          return false
        }
        // 如果文件类型不在允许上传的范围内
        if (this.fileType.includes(FileExt)) {
          return true
        } else {
          this.$message.error('上传文件格式不正确!')
          return false
        }
      }
    },
    /**
     * 点击文件列表中已上传的文件时的钩子
     * @param {*} file
     */
    handlePreview(file) {
      console.log(file)
      this.url = file.url
      this.$refs.preview.clickHandler()
    },
    /**
     * 下载
     * @param {*} file
     */
    handleDownload(file) {

    },
    /**
     * 文件列表移除文件时的钩子
     * @param {*} file
     */
    handleRemove(file) {
      this.$emit('remove', file)
    },
    /**
     * 文件上传成功时的钩子
     * @param {*} response
     */
    handleSuccess(response, file) {
      this.$emit('success', response, file)
    },
    /**
     * 文件上传失败时的钩子
     * @param {*} _err
     */
    handleError(response, file) {
      this.$emit('error', response, file)
    },
    /**
     * 文件上传时的钩子[进度]
     * @param {*} file
     */
    handleProgress(file) {
      console.log(file, '进度')
    },
    /**
     * 自定义上传
     * @param {*} param
     */
    uploadFile(param) {
      const loading = this.$loading({
        lock: true,
        text: '正在读取表格,请稍后...',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      // 获取上传的文件名
      const file = param.file
      // 发送请求的参数格式为FormData
      const formData = new FormData()
      // return
      formData.append('file', file)
      formData.append('agencyId', this.agencyId)
      for (const key in this.data) {
        formData.append(key, this.data[key])
      }
      //   formData.set('file', param.file)
      console.log(param, file, this.agencyId, formData)
      // 调用param中的钩子函数处理各种情况,这样就可以用在组件中用钩子了。也可以用res.code==200来进行判断处理各种情况
      uploadFile(formData).then(res => {
        loading.close()
        if (res.code === 200) {
          console.log(res)
          this.$message.success('上传成功!')
          param.onSuccess(res, file)
        } else {
          console.log(res)
          this.$message.error('上传失败')
          param.onError(res, file)
        }
      }).catch(err => {
        loading.close()
        this.$message.error('上传失败')
        param.onError(err)
      })
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .el-upload-list__item.is-success.focusing .el-icon-close-tip {
  display: none !important;
}
::v-deep .el-upload--picture-card{
    border-radius: 0;
    border: 0;
    height: 100%;
    width: 100%;
    line-height: 100%;
    background: #fff;
}
</style>

使用

<template>
  <div class="details">
      <uploadXlsx
        :limit="99"
        :list="list"
        style="margin-left:10px;"
        @success="success" // 绑定回调函数
      />
  </div>
</template>
<script>
import uploadXlsx from '@/components/upload' // 引入文件
export default {
  components: {
    uploadXlsx
  },
  data() {
    return {
    }
  },
  methods: {
    // 上传成功,回调
    success(res, file) {
      console.log(res, file.name, '上传成功')
    },

  }
}
</script>

猜你喜欢

转载自blog.csdn.net/q12as/article/details/127890109