將檔案暫存於localStorage再取出來|Vue3 JavaScript
Published in
6 min readApr 11, 2024
先開一個input框用來存檔案,以Vuetify為例:
<v-file-input
label="檔案"
density="compact"
variant="outlined"
v-model="data.file"
></v-file-input>
<script>
const data = reactive({
file: null,
});
</script>
將暫存的檔案存進localStorage
const setFile = () => {
if (data.file.length) { // 如果有上傳file的話
const file = data.file[0];
localStorage["filename"] = file.name; // 把要顯示的filename存進local
const reader = new FileReader();
reader.onload = function (event) {
localStorage["file"] = event.target.result;
};
reader.readAsDataURL(file);
}
};
const reader = new FileReader();
- 使用
FileReader()
,web能以非同步方式存取檔案,file主要從<input>
取得,或是拖拉時的DataTransfer
中取得。
reader.onload = function (event) {
localStorage["file"] = event.target.result;
};
reader.readAsDataURL(file);
onload
:事件處理器,於讀取完成時觸發。
參考資料:FileReader
從localStorage
取出該檔案,需要先將dataURL轉換為Blob。
Blob
(Binary large Object)是一種適合讀取文件的物件,從<input type=file>
來拿到的File
物件也是一種特殊的Blob
物件,繼承了Blob的屬性。
參考資料:[知識篇]WebAPIs — Blob
// Data URL => Blob
function dataURLtoBlob(dataURL) {
const byteString = atob(dataURL.split(",")[1]);
const mimeString = dataURL.split(",")[0].split(":")[1].split(";")[0];
const ab = new ArrayBuffer(byteString.length);
const ia = new Uint8Array(ab);
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], { type: mimeString });
}
Blob這個建構式需要兩個參數: newBlob = new Blob(array, options);
所以我們要利用dataURL來組裝一下!
逐行解析dataURLtoBlob
:
const byteString = atob(dataURL.split(",")[1]);
- 利用
atob
函數將Data URL 中的 Base64 的部分,解碼為二進位資料
const mimeString = dataURL.split(",")[0].split(":")[1].split(";")[0];
- 從Data URL 中提取 MIME type(取
:
到;
之間的文字)application/octet-stream
const ab = new ArrayBuffer(byteString.length);
- 將
byteString(剛剛解析好的資料)
丟進ArrayBuffer
中。
參考資料:ArrayBuffer - 但因為
ArrayBuffer
只代表一段記憶體區塊,只能讀不能寫,僅能透過 View 操作其內容。
參考資料:[知識篇]JS Global Objects — ArrayBuffer
const ia = new Uint8Array(ab);
- 利用
Uint8Array()
轉換為TypedArray
for (let i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
- 利用
charCodeAt()
將字串轉為unicode
return new Blob([ab], { type: mimeString });
- 使用
ArrayBuffer
建立 Blob Object,並指定MIME type。
從localStorage
提取file
,並調用dataURLtoBlob
將data URL轉換為Blob,利用new File
建立資料,並將filename
一併帶入。
const getFile = () => {
if (localStorage.hasOwnProperty("file")) {
if (localStorage["file"]) {
const fileData = localStorage["file"];
const fileBlob = dataURLtoBlob(fileData);
const file = new File([fileBlob], localStorage["filename"]);
return file;
}
} else {
return null;
}
};
其實我也是有看沒有懂🥹但我想之後會慢慢了解的,交給未來的我補充了🥹