前言
以 vue 举例,原生 html + css + js 现在应该很少有人去写了
一、绘制样式
绘制两个标签,一个 <div></div> ,一个 <input type="file" />; 为 <div></div>添加 css 样式,并隐藏 <input type="file" /> ; 点击 <div></div> 标签时,调用 <input type="file" />。
<div @click="clickUploader">点击此处上传文件,可以给我添加各种样式哦</div>
<input type="file" style="display: none" ref="uploader" @change="fileChange" />
二、逻辑处理
考虑到项目中可能不止一个地方使用文件上传,为了方便复用,可以把上传的逻辑抽离出来,单独放到一个文件中
在 src 目录下创建 mixins 文件夹,在此文件下创建一个 file.js 文件
file.js
import { upload } from "@/api/file.js";
export default {
methods: {
fileUpload(file) {
let parma = new FormData();
parma.append("file", file);
return new Promise((resolve, reject) => {
upload(parma)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
},
},
};
- 注意1:上传的文件需要放在
FormData对象中 - 注意2:对象中的
key值视具体情况而定,此处的file只是举例 - 注意3:
FormData对象添加新属性的方法是append(key, value)
vue 中的代码如下,引入上面写的 js ,点击 div ,调用 <input type="file" />,并执行上传文件的方法
.vue
<template>
<div>
<div @click="clickUploader">点击此处上传文件</div>
<input type="file" style="display: none" ref="uploader" @change="fileChange" />
</div>
</template>
<script>
import file from "@/mixins/file";
export default {
mixins: [file],
data() {
return {
uploadFileList: [],
};
},
methods: {
// 文件上传
clickUploader() {
this.$refs.uploader.click();
},
// 选择文件
fileChange(e) {
this.fileUpload(e.target.files[0]).then((res) => {
this.uploadFileList = [...this.uploadFileList, res];
});
e.target.value = null; // 清除 input 中的值
},
},
};
</script>
- 注意1:用混入的方式引入
file.js文件 - 注意2:上传完成后需要清除
input中的值,否则无法上传重复文件
三、图片压缩
现在的手机拍照像素都很高,照片动辄十几 Mb ,如果把这么大的文件上传,必然会导致上传速度慢,且会造成极大的资源浪费,因此,我们需要对图片进行压缩
延伸: 除图片外,其它大文件也可以进行处理,比如分段式上传,不过本文就不做赘述了
图片压缩的原理是把图片转成 canvas ,因为我们可以对 canvas 的宽高和分辨率进行自定义,所以可以转成我们想要的大小,这个功能并不难实现,不过这个功能已经有人做出了插件 image-conversion ,本文就不对具体实现过程和原理进行分析了
想要了解话可以在评论区留言,以后或许会考虑写一篇博客专门去分析
npm i image-conversion --save
import * as imageConversion from 'image-conversion';
return new Promise((resolve, reject) => {
imageConversion.compressAccurately(file, 800).then((res) => {
resolve(res);
});
});
四、附:文件后缀名提取
export default {
methods: {
// 获取文件格式(此处是为了显示不同文件图标,并对图标添加自定义颜色,具体可根据需求进行修改)
fileType(e) {
if (!e) {
return false;
}
let [list, fileIcon, format] = [
e.split("."),
{
icon: null,
color: null,
},
];
format = list[list.length - 1];
let format = list[list.length - 1];
switch (format) {
case "xls":
fileIcon = {
icon: "icon-ECEL",
type: "xls",
color: "",
};
break;
case "xlsx":
fileIcon = {
icon: "icon-ECEL",
type: "xlsx",
color: "",
};
break;
case "doc":
fileIcon = {
icon: "icon-WORD",
type: "",
color: "",
};
break;
case "docx":
fileIcon = {
icon: "icon-WORD",
type: "docx",
color: "",
};
break;
case "pptx":
fileIcon = {
name: "icon-PPT",
type: "pptx",
color: "",
};
break;
case "png":
fileIcon = {
icon: "icon-PNG",
type: "png",
color: "",
};
break;
case "jpg":
fileIcon = {
icon: "icon-JPG",
type: "jpg",
color: "",
};
break;
case "jpeg":
fileIcon = {
icon: "icon-JPG",
type: "jpeg",
color: "",
};
break;
case "gif":
fileIcon = {
icon: "icon-GIF",
type: "",
color: "",
};
break;
case "txt":
fileIcon = {
icon: "icon-TXT",
type: "txt",
color: "",
};
break;
case "wps":
fileIcon = {
icon: "icon-WPS",
type: "wps",
color: "",
};
break;
}
return fileIcon;
},
},
};