如何使用Vue与Inertia提交含多行表格的表单?
动态多行表格表单提交方案(Vue.js + InertiaJS + Laravel)
问题场景
基于Vue.js、InertiaJS和Laravel开发项目,现有一个由后端返回交易数据填充的多行表格表单,每行包含账户名称、描述、金额字段,展示功能正常。需要实现:允许用户修改每行输入值,点击保存按钮后,通过InertiaJS将所有行的当前输入值发送至后端处理并存储到数据库。
查阅InertiaJS文档得知,useForm或reactive通常用于预定义字段的表单,但动态多行表格的字段是动态生成的,现有示例无法直接适配,因此需要针对性方案。
解决方案
核心思路:不直接修改props中的只读数据,先将后端返回的交易数据复制到本地响应式数组中,修改操作绑定到本地数组元素,提交时将整个数组作为表单数据发送。同时可结合Inertia的useForm实现表单状态管理(加载状态、错误处理等)。
修改后的完整代码
<script setup> import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue'; import { Head, router, useForm } from '@inertiajs/vue3'; import { ref } from "vue"; const props = defineProps({ Transactions: { type: Array, // 修正:交易数据应为数组类型,原代码写为Object错误 required: true }, Accounts: { type: Array, // 修正:账户列表应为数组类型,原代码写为Object错误 required: true }, }) // 复制后端交易数据到本地响应式数组,避免直接修改props const localTransactions = ref([...props.Transactions]) // 用useForm包裹交易数组,获得表单状态管理能力 const form = useForm({ transactions: localTransactions.value }) function submit() { // 提交到后端批量更新路由,替换为你的实际路由 form.post('/transactions/bulk-update', { onSuccess: () => { // 提交成功后的操作,比如刷新页面或提示 router.reload() }, onError: (errors) => { // 错误处理逻辑 console.error(errors) } }) } </script> <template> <AuthenticatedLayout> <div class="py-12"> <div class="mx-auto max-w-8xl sm:px-6 lg:px-8"> <div class="overflow-scroll bg-white shadow-sm sm:rounded-lg"> <form @submit.prevent="submit"> <table class="table-auto w-full"> <thead> <tr> <th class="text-left p-3">Account</th> <th class="text-left p-3">Description</th> <th class="text-right p-3">Amount</th> </tr> </thead> <tbody> <!-- 用index绑定本地数组元素,确保v-model正确关联 --> <tr v-for="(transaction, index) in localTransactions" :key="transaction.id || index"> <td class="p-3"> <select v-model="localTransactions[index].account_id"> <option v-for="account in Accounts" :key="account.id" :value="account.id" > {{ account.name }} </option> </select> </td> <td class="p-3"> <input type="text" v-model="localTransactions[index].description" class="w-full text-left" > </td> <td class="p-3"> <input type="number" v-model="localTransactions[index].amount" class="w-full text-right" > </td> </tr> </tbody> </table> <button type="submit" :disabled="form.processing" class="mb-4 mt-6 ml-3 inline-block rounded-md bg-blue-500 px-4 py-3 text-xs font-semibold uppercase tracking-widest text-white shadow-sm hover:bg-blue-600 disabled:opacity-50" > {{ form.processing ? 'Saving...' : 'Save' }} </button> </form> </div> </div> </div> </AuthenticatedLayout> </template>
关键说明
- 数据隔离:将props中的
Transactions复制到本地响应式数组localTransactions,避免直接修改Vue只读的props数据 - 表单状态管理:通过
useForm包裹交易数组,获取processing状态控制按钮禁用状态和文本,同时支持成功/错误回调 - 字段绑定:使用数组索引
index绑定输入框的v-model,确保每个输入值正确关联到本地数组的对应交易项 - 后端适配:提交路由需对应Laravel的批量更新接口,示例如下:
Laravel后端处理示例
// routes/web.php Route::post('/transactions/bulk-update', [TransactionController::class, 'bulkUpdate'])->middleware('auth'); // app/Http/Controllers/TransactionController.php public function bulkUpdate(Request $request) { // 验证提交的交易数据 $validated = $request->validate([ 'transactions.*.id' => 'required|exists:transactions,id', 'transactions.*.account_id' => 'required|exists:accounts,id', 'transactions.*.description' => 'required|string', 'transactions.*.amount' => 'required|numeric', ]); // 批量更新交易数据 foreach ($validated['transactions'] as $transactionData) { \App\Models\Transaction::where('id', $transactionData['id']) ->update([ 'account_id' => $transactionData['account_id'], 'description' => $transactionData['description'], 'amount' => $transactionData['amount'], ]); } return redirect()->back()->with('success', '交易数据更新成功'); }
内容的提问来源于stack exchange,提问作者Dave33
相关产品推荐
相关产品推荐

