
本文详解在 Laravel 8 + Inertia.js(Vue 3)项目中,当通过 Inertia.post 删除草稿并重定向回表单页时,useForm 仍显示旧值的根本原因及可靠解决方案,重点在于正确重置表单默认值与状态。
本文详解在 laravel 8 + inertia.js(vue 3)项目中,当通过 `inertia.post` 删除草稿并重定向回表单页时,`useform` 仍显示旧值的根本原因及可靠解决方案,重点在于正确重置表单默认值与状态。
在使用 Inertia.js 构建多步骤表单流程(如「草稿创建 → 跳转编辑 → 删除后返回」)时,一个常见却易被忽视的问题是:即使执行了 form.reset(),表单字段仍显示上一次提交的旧值。这并非缓存或路由问题,而是 useForm 的设计机制所致——它会将初始化时传入的对象作为持久化默认值(defaults),而 reset() 仅将当前表单数据恢复为这些默认值,而非清空。
? 根本原因:form.reset() 不等于“清空”,而是“重置为 defaults”
查看你的初始化代码:
const form = useForm({
value1: props.defaultValues.value1,
value2: props.defaultValues.value2,
value3: props.defaultValues.value3,
});此时 form.defaults() 内部已固化了 value1、value2、value3 的初始值。调用 form.reset() 实际等价于:
form.value1 = form.defaults().value1; // 即原 props.defaultValues.value1 // ... 其他字段同理
因此,无论你设置 preserveState: false 还是触发 onSuccess,只要未更新 defaults,reset() 就永远无法真正清空字段。
✅ 正确解法:先更新 defaults,再 reset
你需要在删除操作成功后,显式将所有字段的默认值设为 null(或空字符串/初始值),再执行 reset():
const deleteDraft = () => {
if (confirm("确定删除草稿?")) {
Inertia.post(props.deleteDraftUrl, null, {
preserveState: false,
onSuccess: () => {
// ✅ 关键步骤:重置所有字段的默认值为 null
form.defaults({
value1: null,
value2: null,
value3: null,
});
form.reset(); // 此时才会真正清空 UI
},
});
}
};? 通用化处理:动态清空所有字段(推荐用于字段较多场景)
若表单字段数量大或结构动态,可遍历当前表单数据键自动重置 defaults:
onSuccess: () => {
// 动态获取所有字段名,并设默认值为 null
Object.keys(form.data()).forEach(key => {
form.defaults(key, null);
});
form.reset();
}? 注意:form.data() 返回当前表单响应式对象的原始键值对(非 Proxy),安全可靠。
⚠️ 重要注意事项
-
remember: ["form"] 是隐患来源之一:你当前组件启用了 remember: ["form"],它会将 useForm 实例状态持久化到浏览器内存。在删除后跳转场景中,应移除该配置,否则即使重置 defaults,Inertia 可能从 remembered 状态恢复旧数据。✅ 建议改为:
// 移除或注释掉这一行 // remember: ["form"],
- preserveState: false 作用有限:它仅防止 Inertia 缓存服务器返回的页面 props(如 defaultValues),但不影响客户端 useForm 自身的 defaults 和 remember 行为。
-
服务端需确保重定向时 defaultValues 为空:Laravel 控制器在重定向回首屏时,应传递空对象或明确 null 值,例如:
return redirect()->route('form.index')->with(['defaultValues' => [ 'value1' => null, 'value2' => null, 'value3' => null, ]]);
✅ 最终优化版代码(含健壮性处理)
import { useForm } from "@inertiajs/inertia-vue3";
import { Inertia } from "@inertiajs/inertia";
export default {
props: {
pageTitle: String,
defaultValues: Object,
},
// ⚠️ 移除 remember: ["form"] —— 避免状态污染
setup(props) {
const form = useForm({
value1: props.defaultValues?.value1 ?? null,
value2: props.defaultValues?.value2 ?? null,
value3: props.defaultValues?.value3 ?? null,
});
const deleteDraft = () => {
if (confirm("确定删除草稿?")) {
Inertia.post(props.deleteDraftUrl, null, {
preserveState: false,
onSuccess: () => {
// 动态清空所有字段默认值
Object.keys(form.data()).forEach(key => form.defaults(key, null));
form.reset();
// 可选:手动清空输入框(兜底)
form.transform(data => Object.fromEntries(
Object.keys(data).map(k => [k, null])
));
},
});
}
};
return { form, pageTitle, deleteDraft };
},
};通过以上方案,你将彻底解决「删除后返回表单页仍显示旧值」的问题,确保用户体验一致、逻辑清晰可控。核心口诀:重置表单 ≠ 重置默认值;清空 UI,必先清空 defaults。










