前端不止写页面,这些文件操作你必须会!(基础篇)

一、前言

还以为前端只能写页面、调接口、撸样式?其实在你不经意之间,我们早已悄悄摸上了“文件操作”的高地。从用户拖进来的一个 Excel 表处理,到实现分片上传、断点续传、预览下载……前端工程师正在变得越来越像“全能选手”。

这一篇文章不讲概念套话,带你边学边做,手把手搞定文件处理的各种“骚操作”。对新手小白友好,读完它,你将收获一份“文件操作锦囊”。

二、文件操作原理

在开始实现文件操作之前,我们需要了解几个基本的文件相关对象:

File:通过input标签读过来的文件对象

Blob:是类文件对象,用来表示不可变的原始数据,包含很多操作方法

FileReader:文件读取器,将文件读取为某种格式(如 base64、ArrayBuffer、Text)。

FormData:是专门用于和后端交互的对象,允许将 File 对象等数据打包成表单格式发送给后端。

1.File、Blob对象

File是Blob的子类,具有Blob的所有功能,因此我们通常不需要专门使用Blob

在实际开发中,我们一般不会直接 new 一个 File或 Blob 对象

可以直接通过 input 标签选择文件的change事件中获取到 File 对象。

比如:

// 监听change事件
<input type="file" name="file" @change="fileChange" multiple />

// 通过e.target.files获取到选取的文件对象数组
function fileChange(e) {
  fileObj = e.target.files[0] // 获取选择的第一个文件,这时候得到的就是一个文件对象
}
2.FileReader文件读取器

FileReader通常只有在使用第三方库或者要对文件进行特殊处理时使用

一般情况下直接使用File对象就可以了

需要注意的是,FileReader的读取操作是异步的、需要在onload方法中获取结果

我们可以定义FileReader的onload方法,等待它执行完毕后获取到处理后的文件数据

可以利用 Promise+await 确保操作顺序

比如:

const handle = async (e) => {
  let file = e.raw// 从el-table中获取选中数据,是一个file对象
  if (!file) return
  let data = await readFile(file)// 将文件放入定义的读取方法中读取,并使用await等待结果
}

function readFile(file) {
  return new Promise((resolve) => {// 使用Promise管理异步操作
    let reader = new FileReader()// 创建一个FileReader实例
    reader.readAsArrayBuffer(file)// 将文件读取为ArrayBuffer格式
    reader.onload = (e) => {// 因为读取是异步的,所以在onload方法中获取
      resolve(e.target.result)// 返回处理结果
    }
  })
}
3.FormData

首先我们要明白,前端的File对象后端是无法直接识别的

这时候就需要FormData挂载File对象传给后端

也可以使用FileReader文件读取器将File对象读取为base64、text格式传给后端

(ps:读取为base64格式时可以做预览图效果,直接放入img的scr中替换路径即可)

比如:

示例1
// 创建一个新的 FormData 对象
const formData = new FormData();

// 将文件和其他数据添加到 FormData 对象
formData.append("file", fileInput.files[0]);  // 添加文件
formData.append("username", usernameInput.value);  // 添加用户名

// 上传文件时直接把formData传过去就可以了
cosnt res = await uploadFileAPI(formData)

示例2
// 如果想将已经定义好了的对象转为FormData,可以结合遍历方法实现
// 注意转化只是一个比喻,实际上还是通过append修改FormData实例
const data = {
  name: 'John Doe',
  email: 'john.doe@example.com',
  age: 30
};

// 创建 FormData 对象
const formData = new FormData();

// 使用 Object.entries 遍历对象并将每个键值对添加到 FormData
Object.entries(data).forEach(([key, value]) => {
  formData.append(key, value);
});

// 现在你可以使用 formData 进行表单提交了
cosnt res = await uploadFileAPI(formData)

三、完整代码演示(分片上传)

接下来,让我们用 Vue 3 来实现一个简单的文件上传和分片上传的示例。

<script setup>
import { ref } from 'vue'

// 存储图像的base64编码,用于显示预览
const imgbase64 = ref()

// 存储文件对象
let fileObj

// 存储上传进度
let percentage = ref(0)

// 文件选择变化时触发,获取文件对象
function fileChange(e) {
  fileObj = e.target.files[0] // 获取选择的第一个文件
}

// 提交文件的函数
const submit = async () => {
  // 设置每个分片的大小为2MB
  let size = 2 * 1024 * 1024
  let current = 0 // 当前上传的位置

  // 分片上传文件
  const post = () => {
    if (current > fileObj.size) return // 如果上传的字节数超过文件总大小,停止上传

    // 创建 FormData 对象,用于将文件分片添加到请求中
    const _formData = new FormData()
    const data = fileObj.slice(
      Math.max(0, current), // 取当前分片的起始位置
      Math.min(current + size, fileObj.size) // 取当前分片的结束位置
    )
    _formData.append(fileObj.name, data) // 将分片添加到 FormData

    // 使用 setTimeout 模拟异步请求,真实情况可用 async/await 和 fetch 代替
    setTimeout(() => {
      current += size // 更新当前上传位置
      percentage.value = Math.min((current / fileObj.size) * 100, 100).toFixed(2) // 计算上传进度并显示
      console.log(percentage.value) // 打印上传进度

      post() // 递归上传下一个分片
    }, 10) // 模拟延迟上传
  }

  post() // 调用 post 函数开始上传
}
</script>

<template>
  <div>
    <!-- 文件选择框,绑定 fileChange 方法 -->
    <input type="file" name="file" @change="fileChange" multiple />
    
    <!-- 图像预览(如果选择了图片文件) -->
    <img :src="imgbase64" />
    
    <!-- 显示上传进度 -->
    <br />
    <div>进度 {{ percentage }}%</div>
    
    <!-- 提交按钮,点击后触发 submit 方法 -->
    <br />
    <el-button @click="submit">提交</el-button>
  </div>
</template>

<style lang="scss" scoped>
img {
  width: 200px;  // 设置预览图像的宽度
  height: 200px; // 设置预览图像的高度
}
</style>

四、结语

希望这篇文章能帮助大家理解前端文件操作的原理,在实际开发中面对文件操作得心应手。

本次主要介绍了文件操作的基础原理,文件操作的世界远不止上传与预览。

在下一篇文章中,我们将深入探索前端如何处理 Excel 和 Word 文档

包括如何读取内容、格式转换、导出下载等实用技巧。

不管你是要做数据报表、合同生成,还是在线文档预览,都是实打实的刚需技能。

敬请期待,下一站——玩转Excel、Word

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值