前端文件上传

前端上传文件的形式有两种

  • 二进制传输 用二进制流的形式传输
  • Base64 把文件转为base64字符串传输

 文件相关js对象解析

  • Blob对象 把文件转化为二进制形式获取为blob对象
  • File 通过input标签读取过来的对象(file对象是blob对象的子类所以blob对象的方法file对象也可的使用如slice方法)
  • FormData 可以用来搭载blob对象来传输
  • FileReader 多用于把文件读取为某种形式,如文本,base64

代码接口部分都为伪代码自己定义即可 

 FormData搭载二进制形式上传文件

4.	<script setup>
5.	import axios  from 'axios'
6.	const f1 = (e) => {
7.	  //获取到file对象
8.	  const file = e.target.files[0]
9.	  //限制文件大小
10.	  if(file.size > 100000) {
11.	    alert('文件不能大于10kb')
12.	    e.target.value = ''
13.	    return
14.	  }
15.	  //限制文件后缀名
16.	  const name = file.name.split('.')[1]
17.	  if(name!== 'docx') {
18.	    alert('文件类型必须是docx')
19.	    e.target.value = ''
20.	    return
21.	  }
22.	  //通过FormData可以用来搭载数据来传输
23.	  //1.新建formData对象
24.	  const from = new FormData()
25.	  //通过append 方法加入文件
26.	  from.append('file',file)
27.	  axios.post('/xxx',from)
28.	}
29.	</script>
30.	
31.	<template>
32.	  <div>
33.	    <input type="file" @change="f1" />
34.	  </div>
35.	</template>
36.	
37.	<style scoped>
38.	</style>

 FileReader把文件读取为base64的形式上传

40.	<script setup>
41.	import {ref} from 'vue'
42.	import axios  from 'axios'
43.	const imgUrl = ref('')
44.	const f1 = (e) => {
45.	  //获取到file对象
46.	  const file = e.target.files[0]
47.	  //限制文件大小
48.	  if(file.size > 1000000) {
49.	    alert('文件不能大于100kb')
50.	    e.target.value = ''
51.	    return
52.	  }
53.	  //限制文件后缀名
54.	  const name = file.name.split('.')[1]
55.	  if(name!== 'jpeg') {
56.	    alert('文件类型必须是docx')
57.	    e.target.value = ''
58.	    return
59.	  }
60.	  const fileReader = new FileReader()
61.	  fileReader.readAsDataURL(file)
62.	  fileReader.onload = () => {
63.	    //缩略图
64.	    console.log(fileReader.result)
65.	    imgUrl.value = fileReader.result
66.	    axios.post('/xxx',{base64:fileReader.result})
67.	  }
68.	}
69.	</script>
70.	
71.	<template>
72.	  <div>
73.	    <input type="file" @change="f1" />
74.	    <img :src='imgUrl'/>
75.	  </div>
76.	</template>
77.	
78.	<style scoped>
79.	img {
80.	  width: 100px;
81.	}
82.	</style>

多文件上传

<script setup>
import {reactive, ref} from 'vue'
import axios  from 'axios'
const imgArr = reactive([])
const base64Arr = reactive([])
//多文件上传
const f2 = (e) => {
console.log(e.target.files)
const fileList = e.target.files
for(let i=0; i<fileList.length;i++) {
  imgArr.push(fileList[i])
  let fr = new FileReader()
  fr.readAsDataURL(fileList[i])
  fr.onload=()=> {
    base64Arr.push(fr.result)
  }
}
}

const submit = () => {
  imgArr.forEach(file => {
    let form = new FormData()
    form.append(file.name, file)
    axios.post('/xxx',form)
  })
}
</script>

<template>
  <div>
    <input type="file" @change="f2" multiple/>
     <img v-for="(item ,index) in base64Arr" :key="index" :src="item" />
     <button @click="submit" >上传</button>
  </div>
</template>

<style scoped>
img {
  width: 100px;
  height: 100px;
}
</style>

大文件切片上传和断点续传

  • 大文件(获取到文件对象)
  • Slice方法切片(对大文件进行切片)
  • 部分内容(获取到切片后的部分内容进行上传)
  • 记录当前切到哪一位(记录当前上传到哪里)
  • 后端拼接切片 (后端对前端切片内容拼接 前端不需要关注)
<script setup>
import {reactive, ref} from 'vue'
import axios  from 'axios'
let per = ref(0)
let f3 = async(e) => {
  //大文件上传
  let file = e.target.files[0]
  //slice是blob对象的方法,但是file对象是blod对象的子类
  let fileSize = file.size //文件大小
  let current = 0; //开始值
  let size = 2 * 1024 * 1024 //每次传递2M内容
  let localPer = parseInt(localStorage.getItem(file.name))
  if(localPer) {
    current = localPer
  }
  while(current < fileSize) {
    let _sli = file.slice(current,current + size) // 0-2M、2-4M、4-6M ....
    let form = new FormData()
    form.append(file.name,_sli)
    form.append('partIndex',current)
    await axios.post('http://localhost:3000/part',form)
    current += size //每次循环累加current
    localStorage.setItem(file.name,current)
    per.value = Math.min((current/fileSize)*100,100) //Math.min()两个值取最小值 current/fileSize大于1时就会取100
    if(per.value == '100') localStorage.removeItem(file.name)
  }
}
</script>

<template>
  <div>
    <input type="file" @change="f3"/>
    <div>{{per}}</div>
  </div>
</template>

<style scoped>
</style>

实现效果

7cdca6125d7f430587ddf70dd3b4ab07.png

bea50e368ce440398494ce75b9dad3ff.png

代码地址 
司徒飞/vue-file-serverhttps://gitee.com/situ_fei/vue-file-server.git


司徒飞/vue-filehttps://gitee.com/situ_fei/vue-file.git

 

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值