当前位置:首页 > VUE

vue实现上传插件

2026-02-17 11:50:10VUE

Vue 文件上传插件实现

文件上传是 Web 开发中常见的需求,Vue 生态系统中有多种实现方式。以下是几种主流方法:

原生 input 上传

使用 HTML5 的 input 元素配合 Vue 实现基础上传功能:

<template>
  <div>
    <input type="file" @change="handleFileUpload" />
    <button @click="submitFile">上传</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      file: null
    }
  },
  methods: {
    handleFileUpload(event) {
      this.file = event.target.files[0]
    },
    async submitFile() {
      const formData = new FormData()
      formData.append('file', this.file)

      try {
        const response = await axios.post('/upload', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        })
        console.log('上传成功', response.data)
      } catch (error) {
        console.error('上传失败', error)
      }
    }
  }
}
</script>

使用第三方插件

Vue 社区提供了多个成熟的上传组件:

  1. vue-upload-component 安装:npm install vue-upload-component
<template>
  <uploader :options="options" @complete="complete">
    <uploader-unsupport></uploader-unsupport>
    <uploader-drop>
      <p>拖拽文件到此处上传</p>
      <uploader-btn>选择文件</uploader-btn>
    </uploader-drop>
    <uploader-list></uploader-list>
  </uploader>
</template>

<script>
import { Uploader, UploaderBtn, UploaderDrop, UploaderList, UploaderUnsupport } from 'vue-upload-component'

export default {
  components: {
    Uploader,
    UploaderBtn,
    UploaderDrop,
    UploaderList,
    UploaderUnsupport
  },
  data() {
    return {
      options: {
        target: '/upload',
        testChunks: false
      }
    }
  },
  methods: {
    complete() {
      console.log('上传完成')
    }
  }
}
</script>
  1. element-ui 上传组件 适用于使用 Element UI 的项目:
<template>
  <el-upload
    action="/upload"
    :on-success="handleSuccess"
    :before-upload="beforeUpload">
    <el-button type="primary">点击上传</el-button>
  </el-upload>
</template>

<script>
export default {
  methods: {
    beforeUpload(file) {
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isLt2M) {
        this.$message.error('文件大小不能超过2MB')
      }
      return isLt2M
    },
    handleSuccess(response, file) {
      this.$message.success('上传成功')
    }
  }
}
</script>

自定义上传组件

创建可复用的上传组件:

<template>
  <div class="uploader">
    <input 
      type="file"
      ref="fileInput"
      @change="handleFileChange"
      style="display: none" />
    <button @click="$refs.fileInput.click()">选择文件</button>
    <div v-if="file" class="file-info">
      {{ file.name }} ({{ formatFileSize(file.size) }})
      <button @click="upload">上传</button>
    </div>
    <progress v-if="uploading" :value="progress" max="100"></progress>
  </div>
</template>

<script>
export default {
  data() {
    return {
      file: null,
      uploading: false,
      progress: 0
    }
  },
  methods: {
    handleFileChange(e) {
      this.file = e.target.files[0]
    },
    formatFileSize(bytes) {
      if (bytes === 0) return '0 Bytes'
      const k = 1024
      const sizes = ['Bytes', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    },
    async upload() {
      if (!this.file) return

      this.uploading = true
      const formData = new FormData()
      formData.append('file', this.file)

      try {
        await axios.post('/upload', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          },
          onUploadProgress: progressEvent => {
            this.progress = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            )
          }
        })
        this.$emit('upload-success')
      } catch (error) {
        this.$emit('upload-error', error)
      } finally {
        this.uploading = false
      }
    }
  }
}
</script>

高级功能实现

对于需要更复杂功能的场景:

分片上传

async uploadChunks(file) {
  const chunkSize = 1 * 1024 * 1024 // 1MB
  const chunks = Math.ceil(file.size / chunkSize)

  for (let i = 0; i < chunks; i++) {
    const start = i * chunkSize
    const end = Math.min(start + chunkSize, file.size)
    const chunk = file.slice(start, end)

    const formData = new FormData()
    formData.append('file', chunk)
    formData.append('chunkIndex', i)
    formData.append('totalChunks', chunks)
    formData.append('fileName', file.name)

    await axios.post('/upload-chunk', formData)
  }

  await axios.post('/merge-chunks', {
    fileName: file.name,
    totalChunks: chunks
  })
}

拖拽上传

<template>
  <div 
    class="dropzone"
    @dragover.prevent="dragover"
    @dragleave.prevent="dragleave"
    @drop.prevent="drop">
    <p>拖拽文件到此处上传</p>
  </div>
</template>

<script>
export default {
  methods: {
    dragover(event) {
      event.currentTarget.classList.add('dragover')
    },
    dragleave(event) {
      event.currentTarget.classList.remove('dragover')
    },
    drop(event) {
      event.currentTarget.classList.remove('dragover')
      const files = event.dataTransfer.files
      if (files.length) {
        this.handleFiles(files)
      }
    }
  }
}
</script>

以上方案涵盖了从基础到高级的文件上传实现,可根据项目需求选择合适的方案。第三方插件提供更多开箱即用的功能,而自定义组件则提供更高的灵活性和控制权。

vue实现上传插件

标签: 插件上传
分享给朋友:

相关文章

vue 实现上传

vue 实现上传

Vue 实现文件上传 使用 Vue 实现文件上传可以通过原生 HTML 的 <input type="file"> 或第三方库(如 axios、vue-upload-component)完…

vue实现视频上传管理

vue实现视频上传管理

视频上传管理实现方案 前端部分(Vue.js) 使用<input type="file">元素配合<video>标签实现基础上传和预览功能: <template>…

php实现上传

php实现上传

PHP 文件上传实现 HTML 表单设置 创建一个包含文件上传字段的 HTML 表单,确保表单的 enctype 属性设置为 multipart/form-data,这是文件上传必需的设置。 &l…

jquery 上传

jquery 上传

jQuery 文件上传方法 使用 jQuery 实现文件上传可以通过多种方式完成,以下是常见的几种方法: 使用原生表单和 AJAX 创建一个包含文件输入的表单,并通过 jQuery 的 AJA…

vue上传视频实现

vue上传视频实现

使用 <input type="file"> 上传视频 创建文件选择控件,限制文件类型为视频格式(如 .mp4, .webm)。通过 @change 事件监听文件选择,获取 File 对象…

vue实现日历插件

vue实现日历插件

Vue 日历插件实现方案 使用现成组件库 推荐直接使用成熟的 Vue 日历组件,如: V-Calendar:专为 Vue 设计的轻量级日历组件 FullCalendar:功能强大的日历库,有 Vu…