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

相关文章
相关标签/搜索