iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
0
Modern Web

Nuxt - 使用 Vue.js 做 SSR 的第一哩路系列 第 22

22. Nuxt Routing 進階 - 巢狀路由/嵌套路由 (Nested Routes)

Nuxt 路由入門 篇介紹過兩層動態路由

pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue

路由和頁面元件一對一映射

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'users-id',
      path: '/users/:id?',
      component: 'pages/users/_id.vue'
    },
    {
      name: 'slug',
      path: '/:slug',
      component: 'pages/_slug/index.vue'
    },
    {
      name: 'slug-comments',
      path: '/:slug/comments',
      component: 'pages/_slug/comments.vue'
    }
  ]
}

https://ithelp.ithome.com.tw/upload/images/20181106/20103424WoF1Nx5yae.png


當 PM 希望對 slug 相關頁面都加上一個快捷列時,讀者第一時間想到前面介紹的電商頁面拆法

本文會介紹三種拆法,並講解差異,讓讀者暸解巢狀路由/嵌套路由(Nested Routes)的適用情境

在頁面元件重複加上 component

最直覺的莫非如此,哪些頁面需要,import 並修改 template 就對了

_slug/comments.vue

<template>
  <div>
    <short-cut-bar></short-cut-bar>
      
    <!-- 原內容 -->
    <original-comment-content></original-comment-content>
  </div>
</template>

_slug/index.vue

<template>
  <div>
    <short-cut-bar></short-cut-bar>
    
    <!-- 原內容 -->
    <original-slug-list-content></original-slug-list-content>
  </div>
</template>

輕輕鬆鬆做完,為往後埋下禍因

  • slug 有幾個頁面,就得改幾次
  • 某天不想用 <short-cut-bar> 了,得一個個拿掉

得靠人工修改分散各處的程式碼區塊,不方便又容易出包


共用區塊拆成 layout

為了避免人工一一確認,讀者會想把 component 往上拆

給 slug 訂個 layout 吧!

將 slug 頁面 layout'default' 換成 'slug-special'

layouts/default.vue

<template>
  <div>
    <nuxt>
  </div>
</template>

layouts/slug-special.vue

<template>
  <div>
    <short-cut-bar></short-cut-bar>
    <nuxt>
  </div>
</template>

乍看之下問題解決了,實際上依舊得修改 slug 底下所有頁面 layout 設定

你改的檔案還是一樣多、甚至多了個 layout

更嚴重的,隨著時間推移、網站逐漸增加新的頁面、 feature

PM說「users 路由要加帳號功能列」,路由與 Layout 檔不斷發散

pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
-----| index.vue
--| index.vue
layouts/
--| default.vue
--| error.vue
--| slug-special.vue
--| users-special.vue

如此過了幾次功能追加

layouts/
--| default.vue
--| error.vue
--| slug-special-a.vue
--| slug-special-b.vue
--| users-special.vue
--| qa.vue
--| qa-special.vue
--| dashboard.vue
--| dashboard-special.vue

看起來很不妙對吧?更別提你有多少頁面元件要改


巢狀路由/嵌套路由 (Nested Routes) 的概念

巢狀路由不僅指多層路由,Nuxt 提供

  • 子頁面元件可共用父層頁面元件 (下圖 slug 共用區塊)
  • 父層頁面元件可用 <nuxt-child> 定義子頁面插入處

https://ithelp.ithome.com.tw/upload/images/20181106/20103424FQ22exWsA0.png

只需增加與父層路由同名 vue file - _slug.vue

pages/
--| _slug.vue /* /:slug 共用區塊 */
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue

_slug.vue

<template>
  <div>
    <short-cut-bar></short-cut-bar>
    <nuxt-child>
  </div>
</template>

子頁面元件都不用動,是不是很棒


從 Nuxt 編出的路由表可窺見一番

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'users-id',
      path: '/users/:id?',
      component: 'pages/users/_id.vue'
    },
    {
      path: '/:slug',
      component: 'pages/_slug.vue',
      children: [
        {
          name: 'slug',
          path: '',
          component: 'pages/_slug/index.vue',
        },

        {
          name: 'slug-comments',
          path: 'comments',
          component: 'pages/_slug/comments.vue'
        }
      ]
    },
  ]
}

上一篇
21. Nuxt 處理首屏 - `<no-ssr>`
下一篇
23. Nuxt 細說`<nuxt-child>` 和 `<nuxt>`
系列文
Nuxt - 使用 Vue.js 做 SSR 的第一哩路32

尚未有邦友留言

立即登入留言