input type="file"使用

問題:

在實際開發過程當中,會遇到上傳文件的一些需求。可是使用原生的<input type="file" />在使用中存在一些問題html

  • 在未上傳文件時,顯示"no file choosen",用戶界面不友好,不可配置
  • 上傳同一個文件,不會觸發change事件,即便該文件作過修改
  • 用戶若是在上傳過程當中點擊了「取消」,已經上傳的文件會被移除

解決思路

在閱讀了一些源碼以後,總結了以下的解決方案。有點偷樑換柱的意思:vue

  • 將真正的<input type="file" />隱藏,使用自定義的button經過$refs去觸發文件上傳,實現自定義顯示
  • 文件上傳以後,處理完文件,將<input type="file" />value設置爲null,這樣下次即便上傳的是同一個文件,仍然會觸發change事件
  • 使用上述方法,點擊取消文件被移除,可是不影響頁面展現

具體實現

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="https://unpkg.com/vue"></script>
    <title>Vue</title>
</head>

<body>
    <div id="app">
        <button type="button" @click="click">
            <span v-if="fileName">從新上傳</span>
            <span v-else>上傳文件</span>
        </button>
        <span>{{fileName}}</span>
        <input type="file" ref="uploadFile" style="display:none" accept="image/gif, image/jpeg" @change="upload"/>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                fileName: ''
            },
            methods: {
                click () {
                    // 偷樑換柱,觸發文件上傳
                    this.$refs.uploadFile.click();
                },
                upload (event) {
                    let files = event.target.files || event.dataTransfer.files;

                    if (!files.length) {
                        this.fileName = '';
                        return;
                    }
                    this.fileName = files[0].name;

                    // 上傳以後調用接口...
                    let params = new FormData();
                    params.append('file', files[0]);
                    console.log(params);

                    this.$refs.uploadFile.value = null; // 移除文件,能夠保證上傳一樣的文件時,也會觸發change事件
                }
            }
        })
    </script>
</body>

</html>

感想

遇到問題的時候多去看看別人是怎麼寫的,借鑑一下,解決問題的同時可以學習不少東西。app

相關文章
相關標籤/搜索