在vue项目中如何实现类似于nuxt的layout

22 阅读1分钟

嵌套路由 Layout(官方 router 风格)

核心思路

  • Layout 本身是一个路由
  • 页面作为子路由

const routes = [
  {
    path: '/admin',
    component: AdminLayout,
    children: [
      { path: '', component: AdminHome },
      { path: 'users', component: Users }
    ]
  }
]
<!-- AdminLayout.vue -->
<template>
  <Sidebar />
  <router-view />
</template>

这种方案对路由结构有硬性要求,不够灵活,因此不推荐。

基于 vue-router meta 的 Layout 切换

核心思路

  • route中指定layout
  • App.vue中通过component + slot来实现Layout切换

定义Layout组件:

<!-- layouts/DefaultLayout.vue -->
<template>
  <slot />
</template>
<!-- layouts/AdminLayout.vue -->
<template>
  <div class="admin">
    <Sidebar />
    <section>
      <slot />
    </section>
  </div>
</template>

路由配置

// router/index.ts
const routes = [
  {
    path: '/',
    component: () => import('@/pages/Home.vue'),
    meta: { layout: 'default' }
  },
  {
    path: '/admin',
    component: () => import('@/pages/Admin.vue'),
    meta: { layout: 'admin' }
  }
]

App.vue 中动态切换 Layout

<script setup lang="ts">
import { computed } from 'vue'
import { useRoute } from 'vue-router'
import DefaultLayout from '@/layouts/DefaultLayout.vue'
import AdminLayout from '@/layouts/AdminLayout.vue'

const route = useRoute()

const layoutMap = {
  default: DefaultLayout,
  admin: AdminLayout
}

const layout = computed(() => {
  return layoutMap[route.meta.layout || 'default']
})
</script>

<template>
  <component :is="layout">
    <router-view />
  </component>
</template>