Laravel数据通过Vue Router传递至Vue组件失败问题排查
问题:Vue Router切换后,Laravel API数据无法传递到Vue组件
问题描述
我在把Laravel集合转为JSON传递给Vue组件时遇到了一个奇怪的问题:用Laravel Web路由渲染页面时,数据能正常加载并生成单选按钮,但切换到Vue Router管理路由后,数据完全无法传递过来。相关代码如下:
- Laravel API路由(routes/api.php)
Route::get('/maintenance/types', 'Maintenance\MaintenanceTypesController@index');
- Vuex Store代码
import axios from 'axios' import { data } from 'jquery' export default { namespaced: true, state:{ maintenance_types: [] }, getters:{ maintenance_types (state) { return state.maintenance_types } }, mutations:{ PUSH_M_TYPE (state, data) { state.maintenance_types.push(...data) } }, actions:{ async getMaintenanceTypes ({ commit }) { let response = await axios.get('/maintenance/types') commit('PUSH_M_TYPE', response.data.data) } } }
- Vue组件脚本
import { mapGetters, mapActions } from 'vuex' import axios from 'axios' export default { data () { return { form: { description: '', m_type: '' } } }, computed: { ...mapGetters({ maintenance_types: 'maintenance/maintenance_types' }) }, methods: { ...mapActions({ getMaintenanceTypes: 'maintenance/getMaintenanceTypes' }), async submit () { await axios.post('/api/maintenance/store', this.form) } }, mounted () { this.getMaintenanceTypes() } }
- Vue Router配置
import AppMaintenanceForm from './components/maintenance/AppMaintenanceForm.vue' export const routes = [ { path: '/maintenance/form', component: AppMaintenanceForm, name: 'MaintenanceForm' } ]
问题根源
你遇到的核心问题是API请求路径错误,导致Vue Router模式下请求没有发送到后端Laravel API:
Laravel默认会给routes/api.php中的路由自动加上/api前缀(这个配置在app/Providers/RouteServiceProvider.php里),所以你定义的/maintenance/types API路由,实际可访问的地址是/api/maintenance/types。
但在你的Vuex Action里,axios请求的路径是/maintenance/types:
await axios.get('/maintenance/types')
- 当使用Laravel Web路由时,页面由后端渲染,此时浏览器发送
/maintenance/types请求时,后端没有对应的Web路由,可能会 fallback 到API路由(或者你之前无意中用了正确路径); - 当切换到Vue Router的history模式时,前端路由会拦截所有以
/maintenance开头的请求,把/maintenance/types当成一个前端路由去匹配,而不会发送到后端API,自然拿不到数据。
另外,你在组件的submit方法里已经正确使用了/api/maintenance/store的路径,说明你知道API前缀的存在,只是在获取类型的请求里漏加了。
修复方案
修改Vuex Action中的axios请求路径,加上/api前缀:
actions:{ async getMaintenanceTypes ({ commit }) { let response = await axios.get('/api/maintenance/types') commit('PUSH_M_TYPE', response.data.data) } }
额外优化建议
为了避免以后再出现这类路径错误,你可以给axios设置一个基础URL:
// 在项目入口文件(比如main.js)中配置 import axios from 'axios' axios.defaults.baseURL = '/api'
之后所有axios请求就可以省略/api前缀,直接写相对路径:
// Vuex Action里改成 let response = await axios.get('/maintenance/types') // 组件submit方法里改成 await axios.post('/maintenance/store', this.form)
这样既统一了API请求路径,又减少了重复代码。
内容的提问来源于stack exchange,提问作者user3714932
相关产品推荐
相关产品推荐

