JS实现文件上传(文件导入)

vue 中通过 element-plus 库的 el-upload 实现文件上传。

一、请求

axios({
    
    
  url: '#',
  headers: {
    
    
    'Content-Type': 'multipart/form-data'
  },
  method: 'post',
  data: {
    
    } // 需要上传的文件内容
})

axios 请求为例,对于文件上传的接口,上传的请求类型必须是 multipart/form-data,上传的内容不再是 json 格式,而是一个文件类型。data 参数是用于传入文件。

二、HTML

1.我这边是把上传文件放在一个 el-dialog 弹框中,打开弹框再把文件传入,再点击确定进行上传。
2.如果不需要弹框,自行把弹框的步骤忽略就好。
3.如果要实现文件传入后不需要点击按钮自动上传,请自行设置 action或者看其他文章,这篇文章参考意义不大。

<!--   导入   -->
      <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
        <el-upload
          ref="importRef"
          :limit="1"
          action="#"
          accept=".xlsx, .xls"
          :on-remove="(file, fileList) => {removeImportFile(file, fileList)}"
          :on-change="(file, fileList) => (changeImportFile(file, fileList))"
          :on-exceed="exceedImportFile"
          :auto-upload="false"
          drag
        >
          <el-icon class="el-icon--upload"><upload-filled /></el-icon>
          <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          <template #tip>
            <div class="el-upload__tip text-center">
              <span>仅允许导入xls、xlsx格式文件。</span>
              <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
            </div>
          </template>
        </el-upload>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" @click="submitFileForm">确 定</el-button>
            <el-button @click="upload.open = false">取 消</el-button>
          </div>
        </template>
      </el-dialog>

el-upload部分属性的意义:

  • ref:方便在vue中获取DOM节点
  • limit:限制一次上传文件的数量,这里每次只能上传一个文件,实现多个文件上传的话自行在文件获取和接口上传那边修改下
  • action:请求URL,我这里是手动用按钮请求上传,而不是通过组件本身的action传入文件后自动上传,所以这部分没用,可以删掉,也可以像我一样传个#
  • accept:接受上传的文件类型(thumbnail-mode 模式下此参数无效),我这边比较懒类型判断就用组件本身自带的了,其实可以在传入文件的时候自行判断文件类型,我这边是没做处理的,这样简单点,文件大小什么的也没做控制
  • on-remove:文件列表移除文件时的钩子
  • on-change:文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
  • on-exceed:当超出限制时,执行的钩子函数
  • auto-upload:是否自动上传文件
  • drag:是否启用拖拽上传

importTemplate() 下载模板的点击事件根据实际需求看不是不是要模板操作,我这边添加了下模板的下载操作,不需要就自行删除。

三、JS

1.我这边用的是vue3,如果不了解的话勉强看下吧,其实和vue2没啥太大区别。

// 导入
const upload = reactive({
    
    
  // 是否显示弹出层
  open: false,
  // 弹出层标题
  title: ''
})
let fileFormData = reactive(null)

// 监听导入弹框关闭的时候清空列表,防止下次打开文件还在
watch(() => upload.open, () => {
    
    
  if (!upload.open) {
    
    
    proxy.$refs.importRef.clearFiles()
    fileFormData = null
  }
})

// 点击导入按钮,打开弹框
function handleImport () {
    
    
  upload.open = true
  upload.title = '导入'
}

// 移除导入的文件
function removeImportFile (file, fileList) {
    
    
  proxy.$refs.importRef.clearFiles()
  fileFormData = null
}

// 更改导入的文件
function changeImportFile (file, fileList) {
    
    
  fileFormData = new FormData()
  fileFormData.append('file', file.raw)
}

// 上传文件超出个数
function exceedImportFile () {
    
    
  ElMessage.error('文件个数超出限制,请先移除上一个文件')
}

// 下载导入模板
function importTemplate () {
    
    
  const a = document.createElement('a')
  a.href = '可直接下载的链接,如OSS链接'
  a.download = '导入模板.xls'
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
}

// 导入文件上传
function submitFileForm () {
    
    
  if (fileFormData) {
    
    
  axios({
    
    
  	url: '#',
 	headers: {
    
    
    	'Content-Type': 'multipart/form-data'
  	},
 	method: 'post',
  	data: fileFormData // 需要上传的文件内容
	}).then(rea => {
    
    
		upload.open = false
	})
  }
}

这里文件上传最关键的部分就是通过创建一个FormData 对象,把file文件还是以键值对的形式传递给服务器。

猜你喜欢

转载自blog.csdn.net/qq_43651168/article/details/130271014