InertiaJS/VueJS项目中后端验证错误后表单数据状态无法保留的问题咨询
问题分析
你遇到的核心问题是直接依赖了Inertia传递的prop作为可编辑状态。toRefs(props).event本质上是对父级(Inertia)传递的prop的引用,而Inertia在处理表单提交后的响应时,会重新渲染页面组件并更新props——即使返回的props里没有event,组件的event prop也会被重置为初始的后端传递值(或默认值),导致你编辑的状态丢失。
preserveState: true主要用于保留页面滚动位置和组件的内部状态,但它不会阻止Inertia更新组件的props,所以对你的场景不起作用。
解决方案:将prop复制到组件内部状态
正确的做法是把后端传递的event prop复制到组件自己的响应式状态中,这样编辑的是内部状态,不受Inertia props更新的影响。
步骤1:创建内部响应式状态
在组件中,用ref或reactive创建内部状态,并初始化时复制prop的值:
<script setup> import { ref, watch } from 'vue' import { Inertia } from '@inertiajs/inertia' const props = defineProps({ event: { type: Object, default: () => ({}) } }) // 创建内部响应式状态,复制prop的初始值 const event = ref({ ...props.event }) </script>
步骤2:同步prop的更新(可选)
如果后续后端可能会更新event prop(比如编辑场景),可以添加一个监听器,当prop变化时同步到内部状态,同时避免覆盖用户已编辑的内容:
// 监听prop变化,仅在prop有新值时同步 watch(() => props.event, (newEvent) => { if (Object.keys(newEvent).length) { Object.assign(event.value, newEvent) } }, { immediate: true })
步骤3:提交表单时使用内部状态
提交表单时,发送内部的event对象,而不是prop的引用:
const submitForm = () => { Inertia.post(url, event.value, { only: ['global'], preserveState: true // 仍可保留滚动位置等页面状态 }) }
为什么这样有效?
组件内部的响应式状态完全由你控制,不会被Inertia的props更新影响。即使后端返回验证错误的响应,Inertia更新页面props时,你的内部状态依然会保留用户编辑后的内容,不会被重置。
内容的提问来源于stack exchange,提问作者Deric Lima
相关产品推荐
相关产品推荐

