赞
踩
<template> <div> <input type="file" name="file" @change="fileChange" /> <button @click="submit">提交</button> </div> </template> <script setup> function fileChange(e) { // e.target.files[0]表示获取到索引为0的文件 let file = e.target.files[0]; console.log(file); if (file.size > 1024 * 1024 * 10) { alert("文件大小不能超过10M"); return; } if (file.type !== "video/mp4") { alert("文件类型必须是mp4"); return; } } function submit() {} </script>
可以把File 类型 转换为 Blob 类型,因为 File 是Blob的子类
console.log(new Blob([file]));
Blob是不可修改也是无法读取里面的内容的。但是Filereader就提供了读取Blob里面内容的方法。
<template> <div> <input type="file" name="file" @change="fileChange" /> <button @click="submit">提交</button> </div> </template> <script setup> function fileChange(e) { // e.target.files[0]表示获取到索引为0的文件 let file = e.target.files[0]; let fr = new FileReader(); // 做缩略图用readAsDataURL fr.readAsDataURL(file); //fr 读取完成后执行 fr.onload = () => { console.log(fr.result); } } function submit() {} </script>
给图片显示一下
可以利用切片来实现上传半张图片的效果
前端最常见的就是添加一个multiple 属性,这样在上传的时候只要按住Ctrl 就可以选择多个文件了,这样的方式对用户不够友好,因为有些用户是不知道按住Ctrl 可以选择多个文件的,一般来说,用户只会一个文件,一个文件来上传的。
用户不按Ctrl 来选择多个文件,而是一个一个文件上传 就需要我们自己来收集数据了。一般定义一个数组来接收,看下面动图就是符合用户习惯的
图片可以通过转成Base64 的方式,文件一般使用 formData来进行传输,可以说,formData 就是一个载体,负责装载文件
<template> <div> <input type="file" name="file" @change="fileChange" multiple/> <button @click="submit">提交</button> <div v-for="item in imgList" >{{ item.name }}</div> </div> </template> <script setup> import axios from 'axios' import { ref } from 'vue' const imgbase64 = ref(''); const imgList = ref([]) //多文件上传 // 定义全局变量,用来存储文件对象 // 方便后面的submit方法使用 let _fileObj; function fileChange(e) { //多文件上传 //结合 multiple属性,可以上传多个文件, //但需要按住ctrl键来选择多个文件,不符合用户习惯 let files = e.target.files; console.log(files); _fileObj = files; // 如果用户使用ctrl键选择多个文件,需要用concat合并 if (e.target.files.length > 1) { imgList.value.concat(e.target.files) //用户一个一个选择文件,直接push存储起来,符合用户习惯 } else { imgList.value.push(e.target.files[0]) } } function submit() { // 文件要传递给后端的话,必须需要用FormData。 // 图片可以直接用base64传递 let _formData = new FormData(); _formData.append('user', '张三'); _formData.append('file', _fileObj); axios.post('/XXX',_formData) } </script>
上面是提交单个文件的,如果想要提交多个文件,只需要遍历即可
把 下面的
let _formData = new FormData();
_formData.append('user', '张三');
_formData.append('file', _fileObj);
axios.post('/XXX', _formData)
改成
//多文件上传,遍历数组,每个文件都要用FormData包装一下
imgList.value.forEach((item) => {
let _formData = new FormData();
_formData.append(item.name + 'file', item);
axios.post('/XXX',_formData)
})
<template> <div> <input type="file" name="file" @change="fileChange" multiple /> <div>{{ Percentage }}%</div> <button @click="submit">提交</button> <div v-for="item in imgList">{{ item.name }}</div> </div> </template> <script setup> import axios from "axios"; import { ref } from "vue"; const imgbase64 = ref(""); const imgList = ref([]); //多文件上传 const Percentage = ref(0); //上传进度 // 定义全局变量,用来存储文件对象 // 方便后面的submit方法使用 let _fileObj; function fileChange(e) { // 切片上传 _fileObj = e.target.files[0]; } async function submit() { let size = 2 * 1024 * 1024; //每片2M let fileSize = _fileObj.size; let current = 0; while (current < fileSize) { let _formData = new FormData(); let fileData = _formData.append(_fileObj.name, _fileObj.slice(current, current + size)); // 这个接口只是用来测试,只有一个功能,就是返回一个‘ok’ await axios.post('http://localhost:4000/upload', fileData) Percentage.value = (current / fileSize * 100)//进度条计算 current += size; } Percentage.value=100 } </script>
server.js文件用来模拟文件上传的,需要引入包:
npm i koa koa-cors koa-router
const Koa = require('koa'); const cors = require('koa-cors'); const koarouter = require('koa-router'); const router = new koarouter(); const app = new Koa(); app.use(cors()); router.post('/upload', async (ctx, next) => { ctx.body ='ok' }) router.post('/upload', async (ctx, next) => { ctx.body ='ok' }) app.use(router.routes()); app.listen(4000);
启动服务器:
node server.js
演示效果
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。