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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 18:15:36