无法获取从 Vue 组件(VILT Stack)发送的 laravel $request 对象上的表单数据

问题描述 投票:0回答:1

这是我面临的问题的快速解释 - (仅 58 秒)

https://komododecks.com/recordings/VKLRr4GiITxAi0XZfqvF


我可以编辑我的帖子,我可以将现有的帖子图像 ID 发送到 Laravel 控制器来删除它们,但是 - 我无法将新图像发送到 Laravel 控制器。

每当我在编辑帖子上添加新图像时,我都会进入空数组。 (请查看上面的视频 - 仅长 58 秒)

这是我的edit.vue 文件


<script setup>
import { useForm, usePage, Link, router } from '@inertiajs/vue3';
import { reactive, ref } from 'vue';
import InputError from '../../Components/InputError.vue';
import UserLayout from '../../Layouts/UserLayout.vue';

const props = usePage().props
const user = reactive(props.auth.user);
const postDetail = reactive(props.postDetail)

const newUploadedImagesToPreview = ref([])
const fileInput = ref(null)

function handleNewImageUpload(event) {
    const newFiles = event.target.files
    if (newFiles) {
        const newFilesArray = Array.from(newFiles)
        form.new_images_to_add.push(...newFilesArray);

        // Making url and push to preview array
        const newFileUrls = newFilesArray.map(image => URL.createObjectURL(image))
        newUploadedImagesToPreview.value.push(...newFileUrls)

        // Clearing Input File Cache To Reset It - so that i could take the same image again
        fileInput.value.value = null
    }
}

function handleRemoveNewlyAddedImages(index) {
    // Must Clear Before Clearing State 
    cleanupImageState(index)

    newUploadedImagesToPreview.value.splice(index, 1)
    form.new_images_to_add.splice(index, 1)

    // Clearing Input File Cache To Reset It - so that i could take the same image again
    fileInput.value.value = null
}



// Only For New Uploaded Image
function cleanupImageState(index) {
    // Make sure we only try to revoke if there's a valid URL at that index
    if (index >= 0 && index < newUploadedImagesToPreview.value.length) {
        const objectUrl = newUploadedImagesToPreview.value[index];
        if (objectUrl) {
            // Revoke the object URL to release memory
            URL.revokeObjectURL(objectUrl);
        }
    }
}

const existingImagesToPreview = ref(postDetail.post_images) // Array

function handleRemoveExistingImages(index) {
    const imgToRemove = existingImagesToPreview.value.at(index)
    existingImagesToPreview.value.splice(index, 1)
    form.remove_image_ids_from_post.push(imgToRemove.id)
}

const form = useForm({
    post_body: postDetail.post_body,
    new_images_to_add: [], // Sending as uploaded file object
    remove_image_ids_from_post: [] // Sending Ids
})

function handleSubmit() {
    console.log("Form data before submission:", form); // Debugging line
    form.submit('put', route('posts.update', postDetail.uuid), {
        onError: (errors) => {
            console.error("Submission errors:", errors);
        }
    });
    // console.log("Form data before submission:", form); // Debugging line
    // form.submit('put', route('posts.update', postDetail.uuid))
    // console.log("Form data before submission:", form); // Debugging line
}

</script>

<template>
    <UserLayout>
        <form @submit.prevent="handleSubmit"
            class="bg-white border-2 border-black rounded-lg shadow mx-auto max-w-none px-4 py-5 sm:px-6 space-y-3">
            <!-- Create Post Card Top -->
            <div>
                <div class="flex items-start /space-x-3/">
                    <!-- User Avatar -->
                    <div class="flex-shrink-0">
                        <img class="h-10 w-10 rounded-full object-cover" :src="user.profileImgUrl"
                            :alt="user.first_name" />
                    </div>
                    <!-- /User Avatar -->

                    <!-- Content -->
                    <div class="text-gray-700 font-normal w-full">
                        <textarea
                            class="block w-full p-2 pt-2 text-gray-900 rounded-lg border-none outline-none focus:ring-0 focus:ring-offset-0"
                            v-model="form.post_body" rows="2"
                            :placeholder="`What's going on, ${user.last_name} ?`"></textarea>
                    </div>
                </div>
                <!-- Existing Images (Preview) -->
                <div v-if="existingImagesToPreview.length" class="mt-5 grid gap-3"
                    :class="(existingImagesToPreview.length > 1) ? 'grid-cols-2' : 'grid-cols-1'">
                    <div v-for="(img, index) in existingImagesToPreview" :key="img.id" class="relative">
                        <img class="rounded-md" :src="img.url">
                        <svg @click="handleRemoveExistingImages(index)" xmlns="http://www.w3.org/2000/svg" fill="none"
                            viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
                            class="size-6 absolute top-3 right-3 hover:stroke-red-500 cursor-pointer">
                            <path stroke-linecap="round" stroke-linejoin="round"
                                d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
                        </svg>
                    </div>
                </div>
                <!-- New Uploaded Images (Preview) -->
                <div v-if="newUploadedImagesToPreview.length" class="mt-5 grid gap-3"
                    :class="(newUploadedImagesToPreview.length > 1) ? 'grid-cols-2' : 'grid-cols-1'">
                    <div v-for="(img, index) in newUploadedImagesToPreview" :key="index" class="relative">
                        <img class="rounded-md" :src="img">
                        <svg @click="handleRemoveNewlyAddedImages(index)" xmlns="http://www.w3.org/2000/svg" fill="none"
                            viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
                            class="size-6 absolute top-3 right-3 hover:stroke-red-500 cursor-pointer">
                            <path stroke-linecap="round" stroke-linejoin="round"
                                d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
                        </svg>
                    </div>
                </div>

                <!-- Input Errors -->
                <InputError :field="form.errors.post_body" />
                <InputError :field="form.errors.new_images_to_add" />
            </div>

            <!-- Create Post Card Bottom -->
            <div>
                <!-- Card Bottom Action Buttons -->
                <div class="flex items-center justify-between">
                    <div class="flex gap-4 text-gray-600">
                        <!-- Upload Picture Button -->
                        <div>
                            <input type="file" ref="fileInput" @change="handleNewImageUpload" name="picture" multiple
                                id="picture" class="hidden" />
                            <label for="picture"
                                class="-m-2 flex gap-2 text-xs items-center rounded-full p-2 text-gray-600 hover:text-gray-800 cursor-pointer">
                                <span class="sr-only">Picture</span>
                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
                                    stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
                                    <path stroke-linecap="round" stroke-linejoin="round"
                                        d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
                                </svg>
                            </label>
                        </div>
                        <!-- /Upload Picture Button -->

                        <!-- GIF Button -->
                        <!--                <button-->
                        <!--                  type="button"-->
                        <!--                  class="-m-2 flex gap-2 text-xs items-center rounded-full p-2 text-gray-600 hover:text-gray-800">-->
                        <!--                  <span class="sr-only">GIF</span>-->
                        <!--                  <svg-->
                        <!--                    xmlns="http://www.w3.org/2000/svg"-->
                        <!--                    fill="none"-->
                        <!--                    viewBox="0 0 24 24"-->
                        <!--                    stroke-width="1.5"-->
                        <!--                    stroke="currentColor"-->
                        <!--                    class="w-6 h-6">-->
                        <!--                    <path-->
                        <!--                      stroke-linecap="round"-->
                        <!--                      stroke-linejoin="round"-->
                        <!--                      d="M12.75 8.25v7.5m6-7.5h-3V12m0 0v3.75m0-3.75H18M9.75 9.348c-1.03-1.464-2.698-1.464-3.728 0-1.03 1.465-1.03 3.84 0 5.304 1.03 1.464 2.699 1.464 3.728 0V12h-1.5M4.5 19.5h15a2.25 2.25 0 002.25-2.25V6.75A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25v10.5A2.25 2.25 0 004.5 19.5z" />-->
                        <!--                  </svg>-->
                        <!--                </button>-->
                        <!-- /GIF Button -->

                        <!-- Emoji Button -->
                        <!--                <button-->
                        <!--                  type="button"-->
                        <!--                  class="-m-2 flex gap-2 text-xs items-center rounded-full p-2 text-gray-600 hover:text-gray-800">-->
                        <!--                  <span class="sr-only">Emoji</span>-->
                        <!--                  <svg-->
                        <!--                    xmlns="http://www.w3.org/2000/svg"-->
                        <!--                    fill="none"-->
                        <!--                    viewBox="0 0 24 24"-->
                        <!--                    stroke-width="1.5"-->
                        <!--                    stroke="currentColor"-->
                        <!--                    class="w-6 h-6">-->
                        <!--                    <path-->
                        <!--                      stroke-linecap="round"-->
                        <!--                      stroke-linejoin="round"-->
                        <!--                      d="M15.182 15.182a4.5 4.5 0 01-6.364 0M21 12a9 9 0 11-18 0 9 9 0 0118 0zM9.75 9.75c0 .414-.168.75-.375.75S9 10.164 9 9.75 9.168 9 9.375 9s.375.336.375.75zm-.375 0h.008v.015h-.008V9.75zm5.625 0c0 .414-.168.75-.375.75s-.375-.336-.375-.75.168-.75.375-.75.375.336.375.75zm-.375 0h.008v.015h-.008V9.75z" />-->
                        <!--                  </svg>-->
                        <!--                </button>-->
                        <!-- /Emoji Button -->
                    </div>

                    <div>
                        <!-- Post Button -->
                        <button type="submit"
                            class="-m-2 flex gap-2 text-xs items-center rounded-full px-4 py-2 font-semibold bg-gray-800 hover:bg-black text-white">
                            Save
                        </button>
                        <!-- /Post Button -->
                    </div>
                </div>
                <!-- /Card Bottom Action Buttons -->
            </div>
            <!-- /Create Post Card Bottom -->
        </form>
    </UserLayout>
</template>

<style scoped></style>

这是我的控制器方法


    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $uuid)
    {
        $validatedData  = $request->all();
        dd($validatedData);
        
        $post = Post::where('uuid', $uuid);
        $dataToUpdate = [
            'post_body' => $validatedData['post_body'],
            'excerpt' => Str::limit($validatedData['post_body'], 250, '....'),
        ];
        $post->update($dataToUpdate);

        // Uploading New Images
        if($request->hasFile('post_images')){
            $images = $request->file('post_images');
            foreach ($images as $image){
                $post->addMedia($image)->toMediaCollection(MediaCollection::PostImage);
            }
        }
        return redirect()->route('posts.show', $uuid);
    }

我也收到此错误消息 -

xhr.js:195 
        
        
       PUT http://127.0.0.1:8000/posts/f7a9938e-e138-44c5-bf80-1804351a7fc2 500 (Internal Server Error)

请帮我。

提前致谢。 塔尔哈

当我创建新帖子时 - 我可以添加多个图像,我尝试实现它 - 但没有成功。

这是我的createPost.vue代码

<script setup>
import { useForm, usePage } from '@inertiajs/vue3';
import { reactive, defineProps, ref } from 'vue';
import InputError from './InputError.vue';

// Accepting Props
const props = defineProps({
    rows: {
        type: String,
        required: false,
        default: '3'
    }
})

// Dynamic textarea row control
const textAreaRowControl = reactive({
    rows: props.rows,
    increaseRowNumber() {
        this.rows = 6
    },
    //Assigned this method to custom directive ()
    resetRowNumber() {
        textAreaRowControl.rows = props.rows
    }
})

// Getting User Data
const user = reactive(usePage().props.auth.user);

// Collecting Form Data
const form = useForm({
    post_body: "",
    post_images: [],
})
// Handling Form Submission
function handleSubmit() {
    form.submit('post', route('posts.store'), {
        onSuccess: () => form.reset()
    })
}

// Handling Preview Image
const previewImages = ref([]);

function handleChangePostImages(event) {
    const files = event.target.files;
    if (files) {
        const filesArray = Array.from(files); // Convert FileList to an array
        form.post_images = filesArray;

        // Generate URLs for each file and concatenate with existing previewImages
        const newPreviewImages = filesArray.map(file => URL.createObjectURL(file));
        previewImages.value = [...previewImages.value, ...newPreviewImages]; // Append new URLs to existing ones
    }
}

function removePreviewImage(index) {
    // Remove the image at the specified index from previewImages
    previewImages.value.splice(index, 1);
    // To keep form.post_images in sync with previewImages
    form.post_images.splice(index, 1);
}

</script>

<template>
    <form @submit.prevent="handleSubmit" @click="textAreaRowControl.increaseRowNumber"
        v-click-away="textAreaRowControl.resetRowNumber"
        class="bg-white border-2 border-black rounded-lg shadow mx-auto max-w-none px-4 py-5 sm:px-6 space-y-3">
        <!-- Create Post Card Top -->
        <div>
            <div class="flex items-start /space-x-3/">
                <!-- User Avatar -->
                <div class="flex-shrink-0">
                    <img class="h-10 w-10 rounded-full object-cover" :src="user.profileImgUrl" :alt="user.first_name" />
                </div>
                <!-- /User Avatar -->

                <!-- Content -->
                <div class="text-gray-700 font-normal w-full">
                    <textarea
                        class="block w-full p-2 pt-2 text-gray-900 rounded-lg border-none outline-none focus:ring-0 focus:ring-offset-0 transition-all"
                        v-model="form.post_body" :rows="textAreaRowControl.rows"
                        :placeholder="`What's going on, ${user.last_name} ?`"></textarea>
                </div>
            </div>
            <!-- <div v-if="previewImages.length" class="mt-5"> -->
            <div class="mt-5 grid grid-cols-2 gap-3">
                <!-- {{ previewImages }} -->
                <div v-for="(img, index) in previewImages" :key="index" class="relative" >
                    <img class=" rounded-md" :src="img">
                    <svg @click="removePreviewImage(index)"  xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                        stroke="currentColor" class="size-6 absolute top-3 right-3 hover:stroke-red-500 cursor-pointer">
                        <path stroke-linecap="round" stroke-linejoin="round"
                            d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
                    </svg>
                </div>
            </div>
            <InputError :field="form.errors.post_body" />
        </div>

        <!-- Create Post Card Bottom -->
        <div>
            <!-- Card Bottom Action Buttons -->
            <div class="flex items-center justify-between">
                <div class="flex gap-4 text-gray-600">
                    <!-- Upload Picture Button -->
                    <div>
                        <input type="file" @change="handleChangePostImages" name="picture" multiple id="picture"
                            class="hidden" />

                        <label for="picture"
                            class="-m-2 flex gap-2 text-xs items-center rounded-full p-2 text-gray-600 hover:text-gray-800 cursor-pointer">
                            <span class="sr-only">Picture</span>
                            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5"
                                stroke="currentColor" class="w-6 h-6">
                                <path stroke-linecap="round" stroke-linejoin="round"
                                    d="M2.25 15.75l5.159-5.159a2.25 2.25 0 013.182 0l5.159 5.159m-1.5-1.5l1.409-1.409a2.25 2.25 0 013.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 001.5-1.5V6a1.5 1.5 0 00-1.5-1.5H3.75A1.5 1.5 0 002.25 6v12a1.5 1.5 0 001.5 1.5zm10.5-11.25h.008v.008h-.008V8.25zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
                            </svg>
                        </label>
                    </div>
                    <!-- /Upload Picture Button -->

                    <!-- GIF Button -->
                    <!--                <button-->
                    <!--                  type="button"-->
                    <!--                  class="-m-2 flex gap-2 text-xs items-center rounded-full p-2 text-gray-600 hover:text-gray-800">-->
                    <!--                  <span class="sr-only">GIF</span>-->
                    <!--                  <svg-->
                    <!--                    xmlns="http://www.w3.org/2000/svg"-->
                    <!--                    fill="none"-->
                    <!--                    viewBox="0 0 24 24"-->
                    <!--                    stroke-width="1.5"-->
                    <!--                    stroke="currentColor"-->
                    <!--                    class="w-6 h-6">-->
                    <!--                    <path-->
                    <!--                      stroke-linecap="round"-->
                    <!--                      stroke-linejoin="round"-->
                    <!--                      d="M12.75 8.25v7.5m6-7.5h-3V12m0 0v3.75m0-3.75H18M9.75 9.348c-1.03-1.464-2.698-1.464-3.728 0-1.03 1.465-1.03 3.84 0 5.304 1.03 1.464 2.699 1.464 3.728 0V12h-1.5M4.5 19.5h15a2.25 2.25 0 002.25-2.25V6.75A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25v10.5A2.25 2.25 0 004.5 19.5z" />-->
                    <!--                  </svg>-->
                    <!--                </button>-->
                    <!-- /GIF Button -->

                    <!-- Emoji Button -->
                    <!--                <button-->
                    <!--                  type="button"-->
                    <!--                  class="-m-2 flex gap-2 text-xs items-center rounded-full p-2 text-gray-600 hover:text-gray-800">-->
                    <!--                  <span class="sr-only">Emoji</span>-->
                    <!--                  <svg-->
                    <!--                    xmlns="http://www.w3.org/2000/svg"-->
                    <!--                    fill="none"-->
                    <!--                    viewBox="0 0 24 24"-->
                    <!--                    stroke-width="1.5"-->
                    <!--                    stroke="currentColor"-->
                    <!--                    class="w-6 h-6">-->
                    <!--                    <path-->
                    <!--                      stroke-linecap="round"-->
                    <!--                      stroke-linejoin="round"-->
                    <!--                      d="M15.182 15.182a4.5 4.5 0 01-6.364 0M21 12a9 9 0 11-18 0 9 9 0 0118 0zM9.75 9.75c0 .414-.168.75-.375.75S9 10.164 9 9.75 9.168 9 9.375 9s.375.336.375.75zm-.375 0h.008v.015h-.008V9.75zm5.625 0c0 .414-.168.75-.375.75s-.375-.336-.375-.75.168-.75.375-.75.375.336.375.75zm-.375 0h.008v.015h-.008V9.75z" />-->
                    <!--                  </svg>-->
                    <!--                </button>-->
                    <!-- /Emoji Button -->
                </div>

                <div>
                    <!-- Post Button -->
                    <button type="submit"
                        class="-m-2 flex gap-2 text-xs items-center rounded-full px-4 py-2 font-semibold bg-gray-800 hover:bg-black text-white">
                        Post
                    </button>
                    <!-- /Post Button -->
                </div>
            </div>
            <!-- /Card Bottom Action Buttons -->
        </div>
        <!-- /Create Post Card Bottom -->
    </form>
</template>

<style scoped>

</style>
laravel vuejs3 tailwind-css inertiajs
1个回答
0
投票

这是我在控制器中的编辑功能

public function edit($id)
{
    Permission::check(['MANAGE_CONFIGURATION', 'EDIT_CONFIGURATIONS']);
    $product = Product::with('category')->findorfail($id);
    $product['media'] = $product->getMedia('product_images');
    $product_categories = ProductCategory::where('status', 1)->get();
    return Inertia::render('XInventory/Inventory/Products/Create', compact('product', 'product_categories'));
}

现在我显示 vue 文件

async function submit() {
if (hasId.value) {
    form.post('/admin/inventory/products/update/' + props?.product.id, {
        _method: 'PUT',
        onSuccess: () => form.reset(),
    })
} else {
    form.post(route('products.store'), {
        onSuccess: () => form.reset(),
    })
}

}

这对我有用。

© www.soinside.com 2019 - 2024. All rights reserved.