当前位置:首页 > VUE

vue实现压缩上传文件

2026-02-25 19:48:33VUE

压缩上传文件的实现方法

使用HTML5的File API和Canvas进行压缩

前端可以使用HTML5的File API读取文件,对于图片文件可以利用Canvas进行压缩。通过Canvas的drawImagetoDataURL方法调整图片质量,实现压缩效果。

function compressImage(file, quality = 0.8) {
  return new Promise((resolve) => {
    const reader = new FileReader()
    reader.onload = (event) => {
      const img = new Image()
      img.onload = () => {
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')
        canvas.width = img.width
        canvas.height = img.height
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
        canvas.toBlob((blob) => {
          resolve(new File([blob], file.name, { type: 'image/jpeg' }))
        }, 'image/jpeg', quality)
      }
      img.src = event.target.result
    }
    reader.readAsDataURL(file)
  })
}

使用第三方库进行更高效的压缩

对于更复杂的压缩需求,可以使用compressorjs等专业压缩库。这些库提供了更多压缩选项和更好的兼容性。

vue实现压缩上传文件

import Compressor from 'compressorjs'

function compressWithLibrary(file) {
  return new Promise((resolve) => {
    new Compressor(file, {
      quality: 0.6,
      success(result) {
        resolve(result)
      },
      error(err) {
        console.error(err.message)
        resolve(file) // 压缩失败返回原文件
      }
    })
  })
}

文件上传实现

压缩后的文件可以通过axios或其他HTTP库上传到服务器。创建FormData对象并附加压缩后的文件。

vue实现压缩上传文件

async function uploadFile(file) {
  const compressedFile = await compressImage(file)
  const formData = new FormData()
  formData.append('file', compressedFile)

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

进度显示和限制文件大小

上传过程中可以显示进度条,并在压缩前检查文件大小,避免不必要的压缩操作。

function checkFileSize(file, maxSizeMB = 5) {
  const maxSizeBytes = maxSizeMB * 1024 * 1024
  return file.size <= maxSizeBytes
}

// 上传带进度显示
function uploadWithProgress(file, onProgress) {
  const config = {
    onUploadProgress: (progressEvent) => {
      const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total)
      onProgress(percent)
    }
  }
  return axios.post('/upload', file, config)
}

完整组件示例

在Vue组件中整合上述功能,提供完整的文件选择和上传体验。

<template>
  <div>
    <input type="file" @change="handleFileChange" />
    <button @click="upload" :disabled="!file">上传</button>
    <progress v-if="progress >= 0" :value="progress" max="100"></progress>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  data() {
    return {
      file: null,
      progress: -1
    }
  },
  methods: {
    async handleFileChange(event) {
      this.file = event.target.files[0]
    },
    async upload() {
      if (!this.file) return

      const compressedFile = await this.compressImage(this.file)
      const formData = new FormData()
      formData.append('file', compressedFile)

      try {
        await axios.post('/upload', formData, {
          onUploadProgress: (progressEvent) => {
            this.progress = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            )
          }
        })
        this.$emit('upload-success')
      } catch (error) {
        console.error('上传失败', error)
      } finally {
        this.progress = -1
      }
    },
    compressImage(file) {
      // 实现压缩逻辑
    }
  }
}
</script>

标签: 上传文件vue
分享给朋友:

相关文章

课程表vue实现

课程表vue实现

实现课程表的Vue组件 创建课程表需要设计数据结构、布局和交互逻辑。以下是一个基于Vue 3的实现方案: 数据结构设计 const timetableData = ref([ { ti…

vue实现类别

vue实现类别

Vue 实现类别的几种方法 在 Vue 中实现类别功能可以通过多种方式完成,以下是一些常见的方法: 使用 v-bind:class 动态绑定类名 通过对象语法或数组语法动态绑定类名,根据条件添加或移…

vue插件实现

vue插件实现

Vue 插件实现方法 Vue 插件是一种向 Vue 应用程序添加全局功能的机制。插件可以包含全局指令、过滤器、混入、实例方法等。 插件的基本结构 一个 Vue 插件通常是一个对象或函数,需要暴露一个…

vue搜索实现

vue搜索实现

Vue 搜索功能实现方法 基于计算属性的搜索 在 Vue 中可以通过计算属性实现简单的搜索功能。这种方式适合小型数据集,利用 JavaScript 的 filter 方法进行筛选。 data() {…

vue实现日历

vue实现日历

Vue 实现日历的基本方法 使用 Vue 实现日历可以通过自定义组件或借助第三方库完成。以下是两种常见实现方式: 自定义日历组件 创建基于 Vue 的日历组件需要处理日期计算和渲染逻辑。核心是生成当…

vue实现甘特图

vue实现甘特图

使用 Vue 实现甘特图 基于开源库(如 vue-ganttastic) 安装依赖库: npm install vue-ganttastic 示例代码: <template> &l…