//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);
};