Nuxt.js 路由

2020-02-13 17:10 更新
Nuxt.js 依據(jù) pages 目錄結(jié)構(gòu)自動生成 vue-router 模塊的路由配置。

要在頁面之間使用路由,我們建議使用<nuxt-link> 標(biāo)簽。

例如:

<template>
  <nuxt-link to="/">首頁</nuxt-link>
</template>

基礎(chǔ)路由

假設(shè) pages 的目錄結(jié)構(gòu)如下:

pages/
--| user/
-----| index.vue
-----| one.vue
--| index.vue

那么,Nuxt.js 自動生成的路由配置如下:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'user',
      path: '/user',
      component: 'pages/user/index.vue'
    },
    {
      name: 'user-one',
      path: '/user/one',
      component: 'pages/user/one.vue'
    }
  ]
}

動態(tài)路由

在 Nuxt.js 里面定義帶參數(shù)的動態(tài)路由,需要創(chuàng)建對應(yīng)的以下劃線作為前綴的 Vue 文件 或 目錄。

以下目錄結(jié)構(gòu):

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

Nuxt.js 生成對應(yīng)的路由配置表為:

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'
    }
  ]
}

你會發(fā)現(xiàn)名稱為 users-id 的路由路徑帶有 :id? 參數(shù),表示該路由是可選的。如果你想將它設(shè)置為必選的路由,需要在 users/_id 目錄內(nèi)創(chuàng)建一個 index.vue 文件。

:API Configuration generate

警告:generate 命令會忽略動態(tài)路由: API Configuration generate

路由參數(shù)校驗

Nuxt.js 可以讓你在動態(tài)路由組件中定義參數(shù)校驗方法。

舉個例子: pages/users/_id.vue

export default {
  validate ({ params }) {
    // 必須是number類型
    return /^\d+$/.test(params.id)
  }
}

如果校驗方法返回的值不為 true或Promise中resolve 解析為false或拋出Error , Nuxt.js 將自動加載顯示 404 錯誤頁面或 500 錯誤頁面。

想了解關(guān)于路由參數(shù)校驗的信息,請參考 頁面校驗API。

嵌套路由

你可以通過 vue-router 的子路由創(chuàng)建 Nuxt.js 應(yīng)用的嵌套路由。

創(chuàng)建內(nèi)嵌子路由,你需要添加一個 Vue 文件,同時添加一個與該文件同名的目錄用來存放子視圖組件。

Warning: 別忘了在父組件(.vue文件) 內(nèi)增加 <nuxt-child/> 用于顯示子視圖內(nèi)容。

假設(shè)文件結(jié)構(gòu)如:

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

Nuxt.js 自動生成的路由配置如下:

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

動態(tài)嵌套路由

這個應(yīng)用場景比較少見,但是 Nuxt.js 仍然支持:在動態(tài)路由下配置動態(tài)子路由。

假設(shè)文件結(jié)構(gòu)如下:

pages/
--| _category/
-----| _subCategory/
--------| _id.vue
--------| index.vue
-----| _subCategory.vue
-----| index.vue
--| _category.vue
--| index.vue

Nuxt.js 自動生成的路由配置如下:

router: {
  routes: [
    {
      path: '/',
      component: 'pages/index.vue',
      name: 'index'
    },
    {
      path: '/:category',
      component: 'pages/_category.vue',
      children: [
        {
          path: '',
          component: 'pages/_category/index.vue',
          name: 'category'
        },
        {
          path: ':subCategory',
          component: 'pages/_category/_subCategory.vue',
          children: [
            {
              path: '',
              component: 'pages/_category/_subCategory/index.vue',
              name: 'category-subCategory'
            },
            {
              path: ':id',
              component: 'pages/_category/_subCategory/_id.vue',
              name: 'category-subCategory-id'
            }
          ]
        }
      ]
    }
  ]
}

未知嵌套深度的動態(tài)嵌套路由

如果您不知道URL結(jié)構(gòu)的深度,您可以使用_.vue動態(tài)匹配嵌套路徑。這將處理與更具體請求不匹配的情況。

文件結(jié)構(gòu):

pages/
--| people/
-----| _id.vue
-----| index.vue
--| _.vue
--| index.vue

將處理這樣的請求:

PathFile
/index.vue
/peoplepeople/index.vue
/people/123people/_id.vue
/about_.vue
/about/careers_.vue
/about/careers/chicago_.vue

Note: 處理404頁面,現(xiàn)在符合_.vue頁面的邏輯。 有關(guān)404重定向的更多信息,請點擊此處.

命名視圖

要渲染命名視圖,您可以在布局(layout) / 頁面(page)中使用 <nuxt name="top"/> 或 <nuxt-child name="top"/> 組件。要指定頁面的命名視圖,我們需要在nuxt.config.js文件中擴(kuò)展路由器配置:

export default {
  router: {
    extendRoutes (routes, resolve) {
      const index = routes.findIndex(route => route.name === 'main')
      routes[index] = {
        ...routes[index],
        components: {
          default: routes[index].component,
          top: resolve(__dirname, 'components/mainTop.vue')
        },
        chunkNames: {
          top: 'components/mainTop'
        }
      }
    }
  }
}

它需要使用兩個屬性 components 和 chunkNames 擴(kuò)展路由。此配置示例中的命名視圖名稱為 top 。看一個例子:命名視圖 例子。

SPA fallback

您也可以為動態(tài)路由啟用SPA fallback。在使用mode:'spa'模式下,Nuxt.js將輸出一個與index.html相同的額外文件。如果沒有文件匹配,大多數(shù)靜態(tài)托管服務(wù)可以配置為使用SPA模板。生成文件不包含頭信息或任何HTML,但它仍將解析并加載API中的數(shù)據(jù)。

我們在nuxt.config.js文件中啟用它:

export default {
  generate: {
    fallback: true, // if you want to use '404.html'
    fallback: 'my-fallback/file.html' // if your hosting needs a custom location
  }
}

在Surge上實現(xiàn)

Surge 可以處理200.html 和 404.html,generate.fallback默認(rèn)設(shè)置為200.html,因此無需更改它。

在 GitHub Pages 和 Netlify 上實現(xiàn)

GitHub Pages 和 Netlify 自動識別 404.html文件,所以我們需要做的就是將 generate.fallback 設(shè)置為 true!

在 Firebase Hosting 上實現(xiàn)

要在Firebase Hosting上使用,請將 generate.fallback 配置為 true 并使用以下配置(more info):

{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/404.html"
      }
    ]
  }
}

過渡動效

Nuxt.js 使用 Vue.js 的<transition>組件來實現(xiàn)路由切換時的過渡動效。

全局過渡動效設(shè)置

提示 :Nuxt.js 默認(rèn)使用的過渡效果名稱為 page

如果想讓每一個頁面的切換都有淡出 (fade) 效果,我們需要創(chuàng)建一個所有路由共用的 CSS 文件。所以我們可以在 assets/ 目錄下創(chuàng)建這個文件:

在全局樣式文件 assets/main.css 里添加一下樣式:

.page-enter-active, .page-leave-active {
  transition: opacity .5s;
}
.page-enter, .page-leave-active {
  opacity: 0;
}

然后添加到 nuxt.config.js 文件中:

module.exports = {
  css: [
    'assets/main.css'
  ]
}

關(guān)于過渡效果 transition 屬性配置的更多信息可參看 頁面過渡效果API。

頁面過渡動效設(shè)置

如果想給某個頁面自定義過渡特效的話,只要在該頁面組件中配置 transition 字段即可:

在全局樣式 assets/main.css 中添加一下內(nèi)容:

.test-enter-active, .test-leave-active {
  transition: opacity .5s;
}
.test-enter, .test-leave-active {
  opacity: 0;
}

然后我們將頁面組件中的 transition 屬性的值設(shè)置為 test 即可:

export default {
  transition: 'test'
}

關(guān)于過渡效果 transition 屬性配置的更多信息可參看 頁面過渡效果API

中間件

中間件允許您定義一個自定義函數(shù)運(yùn)行在一個頁面或一組頁面渲染之前。

每一個中間件應(yīng)放置在 middleware/ 目錄。文件名的名稱將成為中間件名稱(middleware/auth.js將成為 auth 中間件)。

一個中間件接收 context 作為第一個參數(shù):

export default function (context) {
  context.userAgent = process.server ? context.req.headers['user-agent'] : navigator.userAgent
}

中間件執(zhí)行流程順序:

  1. nuxt.config.js
  2. 匹配布局
  3. 匹配頁面

中間件可以異步執(zhí)行,只需要返回一個 Promise 或使用第2個 callback 作為第一個參數(shù):

middleware/stats.js

import axios from 'axios'

export default function ({ route }) {
  return axios.post('http://my-stats-api.com', {
    url: route.fullPath
  })
}

然后在你的 nuxt.config.js 、 layouts 或者 pages 中使用中間件:

nuxt.config.js

module.exports = {
  router: {
    middleware: 'stats'
  }
}

現(xiàn)在,stats 中間件將在每個路由改變時被調(diào)用。

您也可以將 middleware 添加到指定的布局或者頁面:

pages/index.vue 或者 layouts/default.vue

export default {
  middleware: 'stats'
}

如果你想看到一個使用中間件的真實例子,請參閱在 GitHub 上的example-auth0。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號