You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中如何清除file类型input框的已选文件名以支持重复上传

问题原因

原生<input type="file">的选中文件记录保存在DOM元素本身的value属性中,仅清空业务绑定的doc_file变量不会同步修改原生DOM的属性,因此会残留文件名;且当input的value未变化时,选择同一个文件不会触发input事件。

解决方案

分两步改造代码即可:

第一步:修改自定义FileInput组件

新增对v-model绑定值的监听,当绑定值重置为null时自动清空原生input的value,同时可暴露重置方法供父组件主动调用:

<template>
    <input type="file" :class="inputClass" accept=".pdf" @input="onFileSelect" ref="fileInput">
</template>

<script>
import {ref, watch} from "vue";

export default {
    name: "FileInput",
    props: {
        inputClass: String,
        // 对齐Vue3 v-model默认props名
        modelValue: [String, null]
    },
    setup(props, {emit}) {
        const fileInput = ref(null)

        const onFileSelect = () => {
            const input = fileInput.value;
            const files = input.files;
            if(files && files[0]) {
                const reader = new FileReader();

                reader.onload = e => {
                    // 同步触发v-model更新和自定义input事件,兼容现有父组件写法
                    emit('update:modelValue', e.target.result);
                    emit('input', e.target.result);
                }

                reader.readAsDataURL(files[0]);
            }
        }

        // 监听v-model绑定值重置为null时,自动清空原生input的文件记录
        watch(() => props.modelValue, (newVal) => {
            if (newVal === null && fileInput.value) {
                fileInput.value.value = ''
            }
        })

        // 暴露主动重置方法,供父组件按需调用
        const reset = () => {
            if (fileInput.value) {
                fileInput.value.value = ''
                emit('update:modelValue', null)
                emit('input', null)
            }
        }

        return {fileInput, onFileSelect, reset}
    }
}
</script>

第二步:父组件适配

现有resetDocumentModel方法已经会把doc_file设为null,改造后子组件会自动监听该变化清空文件输入框,无需额外修改。如果需要主动触发清空,也可以给子组件加ref直接调用reset方法:

<template>
  <!-- 给子组件加ref -->
  <file-input 
    ref="fileInputRef"
    input-class="form-control form-control-sm" 
    v-model="document.doc_file" 
    @input="getBase64File"
  />
</template>

<script>
import {ref} from 'vue'

export default {
  setup() {
    const fileInputRef = ref(null)
    const document = ref({
      // ... other fields
      doc_file: null,            
    })

    const getBase64File = (file) => {
      document.value.doc_file = file
    }

    const resetDocumentModel = () => {
      for(let field in document.value) {
        document.value[field] = null
      }
      // 也可主动调用子组件重置方法,二选一即可
      // fileInputRef.value?.reset()
    }

    return {
      fileInputRef,
      document,
      getBase64File,
      resetDocumentModel
    }
  }
}
</script>

验证效果

表单提交后调用resetDocumentModel,即可看到文件输入框的残留文件名被清空,再次选择同一个文件也能正常触发上传事件。

内容的提问来源于stack exchange,提问作者calin24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 08:36:03