Laravel+Vue+Inertia.js创建页面表单提交报错:Cannot read properties of undefined (reading 'post')
问题排查:Uncaught TypeError: Cannot read properties of undefined (reading 'post')
场景概述
使用Laravel + Vue.js + Inertia.js开发SSR用户创建页面时,提交表单触发错误:Uncaught TypeError: Cannot read properties of undefined (reading 'post')。
代码复现
Vue创建页面代码
<div class="p-6 overflow-hidden bg-white rounded-md shadow-md dark:bg-dark-eval-1"> <div class="mx-auto max-w-7xl sm:px-6 lg:px-8"> <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg"> <div class="p-6 bg-white border-b border-gray-200"> <form @submit.prevent="form.post(route('users.store'))"> <div class="mb-6"> <label for="name" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" >Name</label > <input type="text" name="name" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" placeholder="" /> </div> <div class="mb-6"> <label for="email" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" >Email</label > <input type="email" name="email" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" placeholder="" /> </div> <div class="mb-6"> <label for="password" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" >Password</label > <input type="password" name="password" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" placeholder="" /> </div> <div class="mb-6"> <label for="password_confirmation" class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300" >Confirm Password</label > <input type="password" name="password_confirmation" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" placeholder="" /> </div> <BreezeButton class="bg-blue-600 mr-2"> <button type="submit">Save User</button> </BreezeButton> <BreezeButton class="bg-gray-600 mr-2"> <Link :href="route('users.index')">Cancel</Link> </BreezeButton> </form> </div> </div> </div> </div> <script> import {Link, useForm} from "@inertiajs/inertia-vue3" export default { components : { Link }, setup(){ const form = useForm({ name: '', email: '', password: '', }) return { form } } </script>
User控制器代码
public function store(Request $request){ $users=User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => $request->password, ]); return redirect()->route('users.index') ->with('success','User created successfully.'); }
路由配置
Route::post('/store', [UserController::class, 'store'])->name('users.store');
错误成因
- useForm包版本不兼容:当前导入的
@inertiajs/inertia-vue3是Vue2适配包,Vue3环境下应使用@inertiajs/vue3,导致生成的form实例不包含post方法。 - 表单未绑定form实例:输入框未通过
v-model关联到form字段,既会导致数据无法提交,也可能因form实例未被正确引用触发异常。 - Inertia初始化缺失:若项目根目录的
app.js未正确配置createInertiaApp,useForm无法生成具备提交方法的实例。
解决方案
1. 修正useForm导入路径
将Vue组件中的导入语句替换为:
import { Link, useForm } from '@inertiajs/vue3'
2. 绑定表单控件到form实例
更新setup函数,补充password_confirmation字段,并给所有输入框添加v-model绑定:
setup(){ const form = useForm({ name: '', email: '', password: '', password_confirmation: '' }) return { form } }
模板中输入框示例(以name字段为例):
<input type="text" name="name" v-model="form.name" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" placeholder="Enter name" />
其余字段(email、password、password_confirmation)同理添加对应v-model绑定。
3. 确保Inertia正确初始化
检查resources/js/app.js中的初始化代码,确保包含以下内容:
import { createApp, h } from 'vue' import { createInertiaApp } from '@inertiajs/vue3' import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers' createInertiaApp({ resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')), setup({ el, App, props, plugin }) { return createApp({ render: () => h(App, props) }) .use(plugin) .mount(el) }, })
4. 优化控制器代码(可选)
添加表单验证并加密密码,提升安全性:
use Illuminate\Support\Facades\Hash; public function store(Request $request){ $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:8|confirmed', ]); User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); return redirect()->route('users.index') ->with('success','User created successfully.'); }
内容的提问来源于stack exchange,提问作者kimski
相关产品推荐
相关产品推荐

