自定義檔案上傳功能實現方法

沈鑫Real發表於2018-10-23

本文采用的是vue框架,但是不管什麼框架,原理是相通的,所以希望大家不要將自己的格局侷限在 框架裡。

說句題外話,最近尤雨溪說要開發vue 3.0 了,而且聽說變動挺大的。我倒是覺得其實沒什麼大不了的。我準備趁著這個機會學習一下React,然後找個小專案實踐一下。畢竟學習vue 3.0 也是學,學React也是學,那我更想了解下更多的知識。

檔案上傳功能開發

好了,言歸正傳,使用第三方的元件庫,總是覺得修改起來很麻煩,所以在最近的專案中才決定自己實現一套檔案上傳的功能。

其實使用HTML的input標籤是可以實現檔案選擇功能的,然後再將選擇的檔案通過http請求傳送到後臺就行了。具體程式碼如下:

<input id="upload" type="file">
複製程式碼

通過將input標籤的type設為file就可以實現檔案選取的功能了。然後通過選擇器讀取選取的檔案資訊即可。

let uploadFile = document.querySelector("#uploadMission")
let form = new FormData()
form.append('file', uploadFile.files[0])
form.append('yourData', "helloworld")
複製程式碼

yourData就是你希望傳送給後臺的除了file欄位以外的欄位,請求的引數格式為:

{
    file: 這裡是一大段檔案資訊,
    yourData: helloworld
}
複製程式碼

所以可以根據實際情況進行傳參。

自定義檔案上傳樣式

可是有一個問題,就是:html的樣式很醜,完全不符合UI設計,而且還不好改。所以我採取的方案是:自己定義一個樣式,然後點選的時候實際呼叫原生的input標籤。這樣你想讓樣式展示成什麼樣都行,不過記得要將原生的input標籤進行隱藏哦。具體程式碼如下:

<span class="yourStyle" @click="uploadFile">上傳檔案</span
<input id="upload" type="file" @change="doRealUpload" style="display: none;">
複製程式碼

當點選uploadFile時,主動呼叫input的click事件,觸發檔案選擇功能,選取完檔案之後,檔案會被讀取到input標籤中。我們只需要按照上面檔案上傳功能開發的流程進行處理即可。

有一點需要注意的是:檔案選擇完之後會觸發input標籤的change事件,這時候才能讀取到檔案資訊。所以記得將檔案傳送至後臺的操作放在doRealUpload方法中。

解決重複上傳同一檔案無效問題

經過上面的步驟,其實已經可以實現自定義檔案上傳功能了。但是總有人喜歡將同一個檔案經過修改後重複上傳。但是因為input的change事件是通過檔案路徑來識別是否為同一檔案的,如果檔名或路徑不改,即使檔案內容修改了,在重複上傳時也無法觸發change事件。

本來我想著將upload.files[0]的值置為null不就解決了麼?但是這是隻讀屬性了,根本改不了。然後我又想著,應該會有clear方法,將檔案資訊清空吧?可惜也沒有。。。

場面一度很尷尬,於是我就想出了讓input標籤重新載入的方法,這樣等於是將input標籤進行了初始化,裡面儲存的檔案資訊當然也一併消除啦。

有的人可能會想要通過DOM操作重新生成一個新的同樣的input標籤。這樣當然是可行的。但是這讓我覺得采用的JQuery的老思想,並不合符Vue以資料為核心的原則。所以我利用了Vue中v-if與v-show的特性。

Vue中v-if的標籤每次是重新載入的,而v-show則是在一開始就進行載入,隨後直接讀快取。所以我將input標籤加上v-if,然後每次呼叫uploadFile方法的時候將inputShow置為true,而在檔案上傳成功後的回撥函式中將inputShow置為false。這樣每次點選上傳按鈕的時候都會重新載入一次input標籤,也就是對input進行初始化操作。

具體程式碼如下:

uploadFile() {
    const vm = this
    vm.inputShow = true
    setTimeout( () => {
        let uploadFile = document.querySelector("#upload")
        uploadFile.click()
    }, 100)
}
複製程式碼

這裡之所以要加setTimeout方法,是因為不加的話可能會因為程式碼執行速度比DOM的渲染速度要快而導致,在執行選擇操作的時候報錯。因為執行click事件的時候input標籤還沒建立完成呢。

結束語

到這裡我們的自定義檔案上傳功能就完成啦。如果你喜歡本篇文章記得點關注哦,你的支援是我繼續分享的最大動力。

相關文章