Inertia提交请求后路由变更:如何在同组件动态展示数据?
关于Inertia组件提交后路由跳转的问题处理
我在使用Inertia时遇到了一个问题:我有一个Detail组件,包含API密钥输入框和提交按钮,希望提交请求返回响应后,在组件内渲染数据列表。但当前提交后路由会跳转到/get-lists,而不是仅刷新组件数据。
Vue组件代码
<script setup> defineProps({ connection: Object, lists: Array }) const form = useForm({ api_key: null, }) function submit() { form.post('/get-lists', { only: ['lists'], }) } </script> <template> <form @submit.prevent="submit"> <InputText type="text" v-model="form.api_key" /> <div v-if="form.errors.api_key">{{ form.errors.api_key }}</div> <Button :disabled="form.processing" type="submit" label="Submit" /> </form> <template v-for="list in lists" :key="list.id"> {{ list.name }} </template> </template>
Laravel控制器代码
public function getLists(Request $request): Response { $client = new Client($request->get('api_key')); $response = $client->list(); return Inertia::render('Details', [ 'lists' => $response['lists'], ]); }
当前问题与疑问
请求发送后数据能正常展示,但路由变为/get-lists。我原本以为返回同一组件时,Inertia会仅刷新组件数据而非跳转路由。考虑过返回JSON响应并在onSuccess钩子处理数据,但Inertia要求返回InertiaResponse,导致无法实现动态SPA效果。想知道我的理解是否有误?是否需要改用Livewire,或者结合Inertia用Axios请求来动态渲染列表?
解决方案
1. 控制器指定原路由(推荐)
在控制器返回Inertia::render时,通过url方法绑定原页面的路由,这样Inertia会更新组件数据但不修改浏览器地址:
public function getLists(Request $request): Response { $client = new Client($request->get('api_key')); $response = $client->list(); return Inertia::render('Details', [ 'lists' => $response['lists'], ])->url(route('details')); // 替换为你的Detail组件对应路由名称 }
2. 表单提交配置replace参数
在表单提交时添加replace: true,让Inertia用新数据替换当前历史记录,而非新增路由条目:
function submit() { form.post('/get-lists', { only: ['lists'], replace: true, }) }
注意:此方法需确保控制器返回的是同一组件。
3. 改用Axios直接请求(纯动态交互)
如果仅需局部更新数据,可跳过Inertia的页面渲染机制,用Axios直接请求并更新本地数据:
修改Vue组件:
<script setup> import axios from 'axios'; import { ref } from 'vue'; defineProps({ connection: Object, lists: Array }) const formApiKey = ref(null); const localLists = ref([]); async function submit() { try { const response = await axios.post('/get-lists', { api_key: formApiKey.value }); localLists.value = response.data.lists; } catch (error) { // 自定义错误处理逻辑 } } </script> <template> <form @submit.prevent="submit"> <InputText type="text" v-model="formApiKey" /> <Button :disabled="false" // 可自行添加loading状态变量 type="submit" label="Submit" /> </form> <template v-for="list in localLists" :key="list.id"> {{ list.name }} </template> </template>
修改控制器返回JSON:
public function getLists(Request $request): JsonResponse { $client = new Client($request->get('api_key')); $response = $client->list(); return response()->json([ 'lists' => $response['lists'], ]); }
关于Livewire的选择
如果你的业务场景以局部DOM更新为主,Livewire是更适配的方案;但如果已经基于Inertia构建项目,优先使用上述Inertia原生方案即可,无需切换技术栈。
内容的提问来源于stack exchange,提问作者Torben
相关产品推荐
相关产品推荐

