DOMException: не удалось выполнить replaceState в «Истории» при использовании form.post по инерции

Я пытаюсь реализовать бесконечную прокрутку, используя useIntersectionObserver. Все работает нормально, пока я не прокрутил и не отправил сообщение, возникла ошибка.

Ошибка

DOMException: не удалось выполнить replaceState в «Истории».

веб.php

Route::get('/dashboard', [DashboardController::class, 'index'])->middleware(['auth', 'verified'])->name('dashboard');

Dashboard.vue

<template>
    <Head title = "Dashboard" />

    <AuthenticatedLayout>
        <div class = "py-2">
            <div class = "max-w-7xl mx-auto sm:px-6 lg:px-8">
                <div class = "overflow-hidden">
                    <div class = "py-6 text-gray-900 flex">
                        <section class = "basis-2/5">
                            <h3>Profile</h3>
                            <h3>Logout</h3>
                        </section>
                        <section class = "basis-3/5 px-3">
                            <Form />
                            
                            <div v-if = "posts.data.length" class = "mt-12" id = "posts">
                                <Post
                                    v-for = "post in posts.data"
                                    :key = "post.id"
                                    :post = "post"
                                />

                                <div ref = "bottom" class = "-translate-y-32"></div>
                            </div>
                        </section>
                    </div>
                </div>
            </div>
        </div>
    </AuthenticatedLayout>
</template>

<script setup>

import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { Head } from '@inertiajs/vue3';
import Form from '@/Components/Post/Form.vue';
import Post from '@/Components/Post.vue';
import { onMounted, ref } from 'vue';
import { useIntersectionObserver } from '@vueuse/core';
import axios from 'axios';

const props = defineProps({
    posts: Object
});

const bottom = ref(null);

const { stop } = useIntersectionObserver(bottom, ([{ isIntersecting }]) => {
    if (!isIntersecting) {
        return;
    }

    axios.get(`${props.posts.meta.path}?cursor=${props.posts.meta.next_cursor}`)
        .then((response) => {
            props.posts.data = [...props.posts.data, ...response.data.data];
            props.posts.meta = response.data.meta;

            if (!response.data.meta.next_cursor) {
                stop();
            }
        });
});

onMounted(() => {
    document.addEventListener('click', function (event) {
        if (event.target.matches('.post-body .mention')) {
            if (parseInt(event.target.dataset.id) > 0) {
                alert(event.target.outerText);
            }
        }
    });
});
</script>

Форма.vue

<template>
    <div>
        <form @submit.prevent = "post">
            <div>
                <Tiptap v-model = "form.body" placeholder = "Got something to share?" />

                <!-- <TextArea
                    id = "body"
                    type = "text"
                    class = "mt-4 block w-full"
                    rows = "3"
                    placeholder = "Got something to share?"
                    v-model = "form.body"
                    required
                /> -->
                                    
                <InputError class = "mt-2" :message = "form.errors.body" />
            </div>
            <div class = "mt-3">
                <PrimaryButton :disabled = "form.processing || form.body.length < 1">Post</PrimaryButton>
            </div>
        </form>
    </div>
</template>

<script setup>
import TextArea from '@/Components/TextArea.vue';
import InputError from '@/Components/InputError.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import { useForm } from '@inertiajs/vue3';
import Tiptap from '../Tiptap.vue';

const form = useForm('PostForm', {
    body: ''
});

const post = () => {
    form.post(route('posts.store'), {
        preserveScroll: true,
        preserveState: false,
        onSuccess: (page) => {
            form.reset();

            console.info(page.props)
            //page.props.posts.data = [[], ...page.props.posts.data];
        },
        onFinish: (visit) => {
            console.info(visit)
        }
    });
};
</script>
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
0
70
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я решил эту проблему, переназначив props на ref, затем используя назначенный ref вместо реквизита, а затем используя JSON.parse и JSON.stringify вот так:

const props = defineProps({
    posts: Object
});

const posts = ref(JSON.parse(JSON.stringify(props.posts)));

код аксиомы

axios.get(`${posts.value.meta.path}?cursor=${posts.value.meta.next_cursor}`)
    .then((response) => {
        posts.value.data = [...posts.value.data, ...response.data.data];
        posts.value.meta = response.data.meta;

        if (!response.data.meta.next_cursor) {
            stop();
        }
    });

А в Form.vue я установил preserveState на false, вот так:

const post = () => form.post(route('posts.store'), {
    preserveState: false,
    onSuccess: () => form.reset()
});

Другие вопросы по теме