使用Vue、Inertia、Laravel,如何更新编辑组件中的文件对象?

4dbbbstv  于 2022-11-25  发布在  Vue.js
关注(0)|答案(4)|浏览(128)

我目前有一个编辑页面,它点击一个更新功能,以更新路线对象时,改变。
在这个页面上,如果我直接单击submit,并dd()来自ItineraryController的$request,它将返回所有现有的表单数据,正如预期的那样。
如果我编辑字段中的数据,然后提交它,它将成功返回,并按预期返回完整的请求对象。
但是,如果我在“replace file”选择器中选择了一个文件,那么在提交表单时,整个请求对象将显示为null,因此无法提交。
如何调整此设置,使“替换文件”输入可操作,并使用现有路线数据填充请求对象?
组成部分:

<template>
  <form @submit.prevent="submit">
    <div class="row w-75 m-auto">
      <h1>Edit Itinerary</h1>
      <div class="col-md-6">
        <label for="title">Title</label>
        <input v-model="form.title" class="form-control" name="title" placeholder="Itinerary Title" type="text" />
      </div>
    </div>
    <div class="row w-75 m-auto">
      <div class="col-md-6">
        <label for="gen_narrative">Narrative</label>
        <textarea v-model="form.gen_narrative" class="form-control" name="gen_narrative" placeholder="Itinerary Narrative"></textarea>
      </div>
    </div>
    <div class="row w-75 m-auto">
      <div class="col-md-6">
        <label>Current Photo</label>
        <img :src="assetUrl(props.itinerary.f_photo)" alt="featured photo" />
      </div>
    </div>
    <br />
    <div class="row w-75 m-auto">
      <div class="col-md-6">
        <label for="f_photo">Replace Photo</label>
        <input class="form-control" name="f_photo" type="file" @input="fileChange" />
      </div>
    </div>
    <div class="row w-75 m-auto">
      <div class="col-md-6">
        <label for="authorid">Author Name</label>
        <input v-model="form.authorid" class="form-control" name="authorid" placeholder="Author Name" type="text" />
      </div>
    </div>
    <div class="row w-75 m-auto">
      <div class="col-md-6">
        <button class="btn btn-primary" type="submit">Edit Itinerary</button>
      </div>
    </div>
  </form>
</template>

<script setup>
import { useForm } from "@inertiajs/inertia-vue3";

function assetUrl(path) {
  return process.env.MIX_BASE_URL + "storage/" + path;
}

function fileChange(event) {
  form.f_photo = event.target.files[0];
}

let props = defineProps({
  itinerary: {
    type: Object,
    required: true,
  },
});

let form = useForm({
  title: props.itinerary.title,
  gen_narrative: props.itinerary.gen_narrative,
  f_photo: null,
  authorid: props.itinerary.authorid,
  stops: props.itinerary.stops,
});
let submit = () => {
  console.log(form.title);
  form.patch("/itineraries/" + props.itinerary.id);
  form.reset();
};
console.log(form);
</script>

<style scoped></style>

控制器:

public function edit($id)
{
    $itinerary = Itinerary::find($id);
    return Inertia::render('Itineraries/Edit', [
        'itinerary' => $itinerary,
    ]);
}

public function update(Request $request, $id)
{
    $itinerary = Itinerary::find($id);
    $itinerary->title = $request->title;
    $itinerary->gen_narrative = $request->gen_narrative;
    //upload the photo
    if ($request->hasFile('f_photo')) {
        $itinerary->f_photo = $request->f_photo->store('public/itinerary_photos');
    }
    $itinerary->authorid = $request->authorid;
    $itinerary->save();

    return redirect('/itineraries');
}
dojqjjoe

dojqjjoe1#

let form = useForm({
    forceFormData: true,
    title: props.itinerary.title,
    gen_narrative: props.itinerary.gen_narrative,
    f_photo: null,
    authorid: props.itinerary.authorid,
    stops: props.itinerary.stops
})
xpcnnkqh

xpcnnkqh2#

我能想到的最好的办法就是写你的文件上传内联

<div class="row w-75 m-auto">
            <div class="col-md-6">
                <label for="f_photo">Replace Photo</label>
                <input class="form-control" name="f_photo" type="file" @input="form.f_photo = event.target.files[0]"/>
            </div>
        </div>
mlmc2os5

mlmc2os53#

根据官方文档中的此示例,您可以

<input type="file" @input="form.f_photo = $event.target.files[0]" />
eulz3vhy

eulz3vhy4#

您的问题可能是因为Inertia本身不支持使用put、patch或delete方法的multipart/form-data请求上传文件,如here所述(在“Multipart限制”部分)。
另一种方法是在没有表单帮助器的情况下使用post方法和'put'的_method属性进行提交,如下所示:

Inertia.post("/itineraries/" + props.itinerary.id", {
    _method: 'put',
    f_photo: form.f_photo,
})

相关问题