//HTML
<div
class="upload-wrap"
@dragover.prevent
@drop.prevent="hDrop"
>
<input
type="file"
ref="addFiles"
class="file-style"
:accept="typeList"
name="files"
multiple
@change="doAdd"
/>
<input
type="file"
ref="addFolder"
class="file-style"
:accept="typeList"
name="files"
webkitdirectory
multiple
@change="doAdd"
/>
<div class="drop">
<el-icon style="font-size: 40px; color: #999">
<upload-filled />
</el-icon>
<p class="tips">每张图片上传大小不超过5MB,每个视频不超过500MB,点击/拖拽上传</p>
<el-button @click="addFilesBtn">添加文件</el-button>
<el-button @click="addFolderBtn">添加文件夹</el-button>
</div>
</div>
//css
.upload-wrap {
position: relative;
border: 1px dashed #ccc;
width: 500px;
height: 120px;
.file-style {
display: none;
}
.drop {
margin-top: 10px;
text-align: center;
width: 100%;
.tips {
color: #999;
font-size: 12px;
margin-bottom: 10px;
}
}
}
//js
let addFiles = ref(null);
let addFolder = ref(null);
const typeList = '.jpg, .jpeg, .png, .gif, .mp4, .mov';
// 分割图片名称/后缀
const getFileName = (fileName) => {
const lastIndex = fileName.lastIndexOf('.');
const arr = [fileName.slice(0, lastIndex), fileName.slice(lastIndex)];
return arr;
};
// Upload组件其他参数
const customRequest = async (files) => {
const outsize = []; //超大列表
const fileArr = []; //上传文件列表
const size = item.size / 1024 / 1024;
for (let i = 0; i < files.length; i++) {
const item = files[i];
// 上传队列去重
const flag = upLoadList.find((el) => {
return el.name === item.name;
});
if (!flag) {
// 大于500M 加入超大队列
if (size > 500) {
outsize.push(item.name);
} else {
fileArr.push(item);
}
}
}
if (fileArr.length === 0) return;
// 提示展示
if (outsize.length > 0) {
ElMessageBox({
message: h('p', null, [
outsize.length > 0 &&
h(
'p',
{ style: 'color: red;word-break: break-all' },
`文件:${outsize}体积过大,已去除`
),
h(
'p',
null,
`剩余可上传数量${fileArr.length - outsize.length}个,确认是否上传`
)
]),
showCancelButton: true,
confirmButtonText: '确认'
})
.then(() => {
upListData(fileArr);
})
.catch(() => {
// 取消本次上传
const fileInput = document.querySelector('input[type="file"]');
fileInput.value = '';
});
} else {
upListData(fileArr);
}
};
// 重组upList数据
const upListData = (el) => {
if (el.length === 0) {
return;
}
for (let i = 0; i < el.length; i++) {
const item = el[i];
// 此处用响应式定义obj可以不等reader.onload先添加队列 后修改size跟src
const obj = {
src: '',
name: item.name,
state: '待上传',
size: '',
fileType: item.type,
file: item
};
// 获取资源宽高,src等信息
const reader = new FileReader();
reader.readAsDataURL(item);
reader.onload = (src) => {
obj.src = src.target.result;
// 获取资源宽高 区分图片还是视频
if (file.type.startsWith('image/')) {
const image = new Image();
image.src = URL.createObjectURL(item);
image.onload = (e) => {
obj.size = [e.target.width, e.target.height];
upLoadList.push(obj);
};
} else {
const video = document.createElement('video');
video.src = URL.createObjectURL(item);
video.onloadedmetadata = () => {
obj.size = [video.videoWidth, video.videoHeight];
upLoadList.push(obj);
};
}
};
// upLoadList.push(obj)
}
};
// 拖拽文件处理
const webkitReadDataTransfer = (dataTransfer) => {
let fileNum = dataTransfer.items.length;
const files = [];
// 递减计数,当fileNum为0,说明读取文件完毕
const decrement = () => {
if (--fileNum === 0) {
customRequest(files);
}
};
// 递归读取文件方法
const readDirectory = (reader) => {
// readEntries() 方法用于检索正在读取的目录中的目录条目,并将它们以数组的形式传递给提供的回调函数。
reader.readEntries((entries) => {
if (entries.length) {
fileNum += entries.length;
entries.forEach((entry) => {
if (entry.isFile) {
entry.file((file) => {
readFiles(file, entry.fullPath);
}, readError);
} else if (entry.isDirectory) {
readDirectory(entry.createReader());
}
});
readDirectory(reader);
} else {
decrement();
}
}, readError);
};
// 文件对象
const items = dataTransfer.items;
// 拖拽文件遍历读取
for (let i = 0; i < items.length; i++) {
const entry = items[i].webkitGetAsEntry();
if (!entry) {
decrement();
return;
}
if (entry.isFile) {
readFiles(items[i].getAsFile(), entry.fullPath);
} else {
// entry.createReader() 读取目录。
readDirectory(entry.createReader());
}
}
function readFiles(file, fullPath) {
if (typeList.includes(getFileName(file.name)[1].toLowerCase())) {
// 图片或视频
file.relativePath = fullPath.substring(1);
files.push(file);
}
decrement();
}
function readError(fileError) {
throw fileError;
}
};
// 图片移入触发
const hDrop = (e) => {
webkitReadDataTransfer(e.dataTransfer);
};
// 点击添加文件
const addFilesBtn = () => {
addFiles.value.click();
};
// 点击添加文件夹
const addFolderBtn = () => {
addFolder.value.click();
};
// 选择添加文件
const doAdd = (e) => {
// 文件夹去除其他格式
const newArr = Object.keys(e.target.files).map((key) => e.target.files[key]);
const data = newArr.filter((el) => {
return typeList.includes(getFileName(el.name)[1].toLowerCase());
});
customRequest(data);
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。