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
相关产品推荐
相关产品推荐

