VUE 文件上传

177 阅读1分钟

vue中实现文件上传

  • 前端开发中经常会有文件上传的需求,基于vue本身的上传组件,有时候不能满足定制话开发需求
  • 所以直接自己封装个上传组件,方便后期使用
  • 话不多说,上代码
// index.vue
<template>
  <div class="upload-area">
    <el-button type="primary" @click="handleUpload" size="mini" v-bind="$attrs">{{name}}</el-button>
    <input ref="fileInput" type="file" id="file" name="myfile" style="display: none" @change="handleSelect" />
  </div>
</template>

<script>
import { upload } from './api'
export default {
  name: 'UploadFile',

  props: {
    url: { // 上传接口 eg: /api/upload
      type: String,
      required: true
    },

    name: {
      type: String,
      default: '上传'
    },

    id: { // 上传的id, 根据实际需求确定的参数
      type: String
    }
  },

  methods: {
    handleUpload() {
      this.$refs.fileInput.click()
    },

    handleSelect(e) {
      const file = e.target.files[0]
      if (file !== undefined) {
        const fileTypename = file.name.substring(file.name.lastIndexOf('.'))
        if (fileTypename === '.xlsx') {
          this.openFullScreen('上传中,请耐心等待···')
          upload(this.url, this.formData('file', file)).then((res) => {
            if (res) {
              this.$message.success('导入成功')

              this.$emit('success')
            }
          }).finally(() => {
            this.$emit('complete')
            this.closeLoading()
          })
        } else {
          this.$message.info('请选择正确的文件类型!')
        }
      } else {
        this.$message.info('请选择正确的文件!')
      }

      e.target.value = ''
    },

    showError(errorInfos) {
       const HtmlString = errorInfos.map(item => `<span style="line-height: 20px">${item}; </span>`).join('')
        this.$message.error({
          dangerouslyUseHTMLString: true,
          message: `<div style="height: 300px; overflow: auto">${HtmlString}</div>`,
          duration: 50 * 1000,
          showClose: true
        })
    },
  
    formData(name, file) {
      const form = new FormData()
      form.append(name, file)
      if (this.id) {
        form.append('editionId', this.id)
      }
      return form
    },

    openFullScreen(txt) {
      this.loading = this.$loading({
        lock: true,
        text: txt,
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
    },

    closeLoading() {
      this.loading.close()
    }
  },
}
</script>

<style lang="scss" scoped>
.upload-area {
  display: inline-block;
  margin: 0 10px;
}
</style>
// api.js
import request from '@/utils/request' // 这个是自己封装的公共请求方法

export function upload(url, data) {
	return request({
    url: url,
    method: 'post',
    data,
  })
}

// 使用页面
<upload-file name="导入" url="/configuration/import" :id="id" :disabled="disable" @success="handleImportSuccess"/>
  • 好了,大功告成,哪里需要写哪里