Vue+Laravel编辑表单:如何保留未更新文件的原有数据库值?
问题
开发Vue+Laravel表单,包含两个文件上传字段:
- 创建时未上传文件,对应数据库字段存为NULL,首次上传单个文件时存储正常
- 编辑时仅上传第二个文件,第一个未上传新文件的字段会被更新为NULL
相关代码如下:
视图代码
<tab-content title="Tab B" :before-change="validationFormInfo"> <validation-observer ref="infoRules" tag="form"> <b-row> <b-col md="6"> <b-form-group label="Parties IC" label-for="opartiesic"> <b-form-file v-model="matter.file1" name="file1" placeholder="Choose a file or drop it here..." drop-placeholder="Drop file here..." v-on:change="onChange1" /> <b-card-text class="my-1"> Selected file: <strong>{{ matter.file1 ? matter.file1.name : "" }}</strong> </b-card-text> <b-card-text class="my-1"> Current file: <strong>{{ matter.parties_ic }}</strong> </b-card-text> </b-form-group> <b-form-group label="Company Forms" label-for="compforms"> <b-form-file v-model="matter.file2" name="file2" placeholder="Choose a file or drop it here..." drop-placeholder="Drop file here..." v-on:change="onChange2" /> <b-card-text class="my-1"> Selected file: <strong>{{ matter.file2 ? matter.file2.name : "" }}</strong> </b-card-text> <b-card-text class="my-1"> Current file: <strong>{{ matter.company_forms }}</strong> </b-card-text> </b-form-group> </b-col> </b-row> </validation-observer> </tab-content>
脚本代码
data() { return { matter:{ file1: "", file2: "", _method: "patch" } }; }, methods: { onChange(e) { this.matter.file1 = e.target.files[0]; }, onChange2(e) { this.matter.file2 = e.target.files[0]; }, formSubmit(e) { e.preventDefault(); let existingObj = this; const config = { headers: { 'content-type': 'multipart/form-data' } } let data = new FormData(); data.append("file1", this.matter.file1); data.append("file2", this.matter.file2); data.append('_method', this.matter._method); axios.post(`/api/auth/matter-dispute/${this.$route.params.id}`, data, config) .then(function (res) { existingObj.success = res.data.success; }) .catch(function (err) { existingObj.output = err; }); this.$router.push({name:"matter-management"}) }, } }
控制器更新方法
public function update(Request $request, matter_dispute $matter_dispute) { if ($request->hasFile('file1')) { $file_name = time().'_'.$request->file1->getClientOriginalName(); $file_path = $request->file('file1')->move(public_path('uploads/MatterDispute/'. $matter_dispute->id), $file_name); $request->parties_ic = time().'_'.$request->file1->getClientOriginalName(); $request->parties_ic_path = '/storage/' . $file_path; } if ($request->hasFile('file2')) { $file_name = time().'_'.$request->file2->getClientOriginalName(); $file_path = $request->file('file2')->move(public_path('uploads/MatterDispute/'. $matter_dispute->id), $file_name); $request->company_forms = time().'_'.$request->file2->getClientOriginalName(); $request->company_forms_path = '/storage/' . $file_path; } DB::table('matter_disputes') ->join('matter_dispute_bs', 'matter_disputes.id', '=', 'matter_dispute_bs.matter_disputes_id') ->join('matter_dispute_cs', 'matter_disputes.id', '=', 'matter_dispute_cs.matter_disputes_id') ->where('matter_disputes.id',$matter_dispute->id) ->update([ 'parties_ic' => $request->parties_ic, 'company_forms' => $request->company_forms, ]); }
推测原因:未上传对应文件时,$request->parties_ic或$request->company_forms为NULL,导致更新时覆盖原有值。需要实现未修改文件时保留数据库原有值。
解决方案
1. 前端优化:仅提交选中的文件
当前代码会无条件提交两个文件字段,空值会被传到后端。修改表单提交逻辑,只追加用户选择了新文件的字段:
formSubmit(e) { e.preventDefault(); let existingObj = this; const config = { headers: { 'content-type': 'multipart/form-data' } } let data = new FormData(); // 仅追加存在的文件 if (this.matter.file1) { data.append("file1", this.matter.file1); } if (this.matter.file2) { data.append("file2", this.matter.file2); } data.append('_method', this.matter._method); axios.post(`/api/auth/matter-dispute/${this.$route.params.id}`, data, config) .then(function (res) { existingObj.success = res.data.success; }) .catch(function (err) { existingObj.output = err; }); this.$router.push({name:"matter-management"}) }
2. 后端处理:仅更新有新值的字段
创建一个更新数组,只加入需要修改的字段,避免用空值覆盖原有数据:
public function update(Request $request, matter_dispute $matter_dispute) { $updateData = []; if ($request->hasFile('file1')) { $file_name = time().'_'.$request->file1->getClientOriginalName(); $file_path = $request->file('file1')->move(public_path('uploads/MatterDispute/'. $matter_dispute->id), $file_name); $updateData['parties_ic'] = $file_name; $updateData['parties_ic_path'] = '/storage/' . $file_path; } if ($request->hasFile('file2')) { $file_name = time().'_'.$request->file2->getClientOriginalName(); $file_path = $request->file('file2')->move(public_path('uploads/MatterDispute/'. $matter_dispute->id), $file_name); $updateData['company_forms'] = $file_name; $updateData['company_forms_path'] = '/storage/' . $file_path; } // 仅当有更新字段时执行操作 if (!empty($updateData)) { DB::table('matter_disputes') ->join('matter_dispute_bs', 'matter_disputes.id', '=', 'matter_dispute_bs.matter_disputes_id') ->join('matter_dispute_cs', 'matter_disputes.id', '=', 'matter_dispute_cs.matter_disputes_id') ->where('matter_disputes.id',$matter_dispute->id) ->update($updateData); } }
补充说明
- 前端优化减少不必要的字段提交,后端处理是最后一道保障,即使前端提交空值,也不会覆盖原有数据。
- 编辑页面初始化时,需从后端接口获取
matter.parties_ic和matter.company_forms的值并赋值,确保前端显示正常且不影响提交逻辑。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

