You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue Router 4布局无法渲染子组件问题求助

解决Vue Router 4中Home.vue无法在Main.vue内渲染的问题

问题现象

  • 访问/路径时,仅渲染Main.vue,Home.vue无法在其内部显示
  • 访问/login路径时,FullPage.vue可正常渲染Login.vue
  • 访问不存在的路由时,FullPage.vue可正常渲染404.vue

相关代码

App.vue

<template>
    <router-view></router-view>
</template>
<script>
export default {
    name: 'App'
}
</script>

Main.vue

<template>
    <div>
        main
        <div id="content">
            <div class="content-wrapper">
                <div class="content-area">
                    <router-view></router-view>
                </div>
            </div>
        </div>
    </div>
</template>

Home.vue

<template>
    <div>
        Home
    </div>
</template>

FullPage.vue & Login.vue

<!-- FullPage.vue -->
<template>
    <div class="full-page">
        full page
        <router-view></router-view>
    </div>
</template>

<!-- Login.vue -->
<template>
    <div>
        login form
    </div>
</template>

router.js

import { createRouter, createWebHistory } from 'vue-router'
import { store } from './store/store'

const router = new createRouter({
    history: createWebHistory('/'),
    routes: [
        {
            // MAIN LAYOUT ROUTES
            path: '',
            component: () => import('@/src/layouts/main/Main.vue'),
            meta: { requiresAuth: true },
            children: [
                {
                    path: '/',
                    name: 'home',
                    component: () => import('@/src/views/Home.vue'),
                }
            ],
        },
        // FULL PAGE LAYOUT
        {
            path: '',
            component: () => import('@/src/layouts/full-page/FullPage.vue'),
            children: [
                {
                    path: 'login',
                    name: 'login',
                    component: () => import('@/src/views/pages/Login.vue')
                },
                {
                    path: 'error-404',
                    name: 'error-404',
                    component: () => import('@/src/views/pages/404.vue')
                },
                {
                    path: 'error-403',
                    name: 'error-403',
                    component: () => import('@/src/views/pages/403.vue')
                },
            ]
        },
        // if no match found, redirect to /error-404
        {
            path: '/:pathMatch(.*)*',
            name: 'not-found',
            redirect: '/error-404'
        }
    ],
})

router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        if (store.getters.isAuthenticated) {
            next()
        }
        else {
            next({ name: 'login' })
        }
    }
    else {
        next()
    }

})

export default router

问题原因

  1. 两个顶级路由的path都设置为'',Vue Router匹配时会优先命中第一个,但子路由使用绝对路径/会打破父子路由的嵌套关系——子路由的绝对路径会被视为独立路由,而非父路由的子路由,导致Home.vue无法加载到Main.vue的<router-view>中。
  2. 当把子路由path改为/home时,路径结构符合父子路由的匹配逻辑,所以问题解决,但这不是最优的默认首页配置方式。

解决方案

调整路由配置,让Main.vue作为/路径的父路由,子路由设为默认子路由(空字符串''),同时给FullPage.vue的顶级路由设置明确前缀,避免匹配冲突:

修改后的router.js:

import { createRouter, createWebHistory } from 'vue-router'
import { store } from './store/store'

const router = createRouter({
    history: createWebHistory('/'),
    routes: [
        {
            // MAIN LAYOUT ROUTES
            path: '/',
            component: () => import('@/src/layouts/main/Main.vue'),
            meta: { requiresAuth: true },
            children: [
                {
                    path: '', // 作为父路由的默认子路由
                    name: 'home',
                    component: () => import('@/src/views/Home.vue'),
                }
            ],
        },
        // FULL PAGE LAYOUT
        {
            path: '/pages', // 给FullPage路由设置前缀
            component: () => import('@/src/layouts/full-page/FullPage.vue'),
            children: [
                {
                    path: 'login',
                    name: 'login',
                    component: () => import('@/src/views/pages/Login.vue')
                },
                {
                    path: 'error-404',
                    name: 'error-404',
                    component: () => import('@/src/views/pages/404.vue')
                },
                {
                    path: 'error-403',
                    name: 'error-403',
                    component: () => import('@/src/views/pages/403.vue')
                },
            ]
        },
        // 未匹配路由重定向
        {
            path: '/:pathMatch(.*)*',
            name: 'not-found',
            redirect: '/pages/error-404'
        }
    ],
})

router.beforeEach((to, from, next) => {
    if (to.matched.some(record => record.meta.requiresAuth)) {
        store.getters.isAuthenticated ? next() : next({ name: 'login' })
    } else {
        next()
    }
})

export default router

如果不想给FullPage路由加前缀,也可以调整路由顺序,把FullPage路由放在Main路由之后,但更推荐给不同布局的路由设置明确前缀,避免匹配歧义。

内容的提问来源于stack exchange,提问作者kopz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 05:30:10