创建自定义视图

你创建的每个自定义路由最终都会呈现为一个 “页面”,该页面包含了我们希望在前端展示的所有 HTML 标记和内容。从软件架构的角度来看,这些 HTML 标记和内容,包括元信息、图片和字体,构成了你应用程序的视图或表现层。在 Nuxt 中,我们可以轻松地创建和自定义我们的视图。让我们一起探索构成 Nuxt 视图的要素以及如何自定义它。

理解 Nuxt 视图

Nuxt 中的视图结构由 应用模板HTML head布局页面层 组成。你可以使用它们为你的应用路由创建视图。在一个更复杂的应用中,你会从 API 获取数据来填充它们,而在一个简单的应用中,你可以直接将虚拟数据手动嵌入到其中。我们将在接下来的章节中逐步介绍这些层。在深入了解之前,请花一点时间研究下面的图表,它将为你提供 Nuxt 视图的完整概览:

image 2025 04 17 19 37 29 866
Figure 1. 参考来源:https://nuxtjs.org/guide/views

你可以看到,“文档 - HTML 文件” 是 Nuxt 视图的最外层,其次是 “布局”、“页面” 以及可选的 “页面子组件” 和 “Vue 组件” 层。“文档 - HTML 文件” 是你 Nuxt 应用的应用模板。让我们首先了解这个最基本的层,并在下一节中学习如何自定义它。

自定义应用模板

Nuxt 会在后台为你创建 HTML 应用程序模板,因此你基本上无需操心创建它。然而,如果你愿意,你仍然可以自定义它,例如添加脚本或样式。默认的 Nuxt HTML 模板非常简单,如下所示:

<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
    <head>{{ HEAD }}</head>
    <body {{ BODY_ATTRS }}>{{ APP }}</body>
</html>

如果你想更改或覆盖此默认模板,只需在你的根目录下创建一个 app.html 文件。看下面的例子:

// app.html
<!DOCTYPE html>
<!--[if IE 9]><html lang="en-US" class="lt-ie9 ie9" {{ HTML_ATTRS
                    }}><![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--><html {{ HTML_ATTRS }}><!--<![endif]-->
<head>
    {{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>

重启你的应用程序,你应该会看到你的自定义 app HTML 模板已经替换了 Nuxt 的默认模板。

你可以在我们的 GitHub 仓库的 /chapter-4/nuxt-universal/view/app-template/ 目录下找到这个例子。

最接近 HTML 文档(即 <html> 元素)的下一层是 HTML 的头部,即 <head> 元素,它包含重要的元信息以及页面的脚本和样式。我们不会直接在 app 模板中添加或自定义这些数据,而是在 Nuxt 配置文件和 /pages/ 目录下的文件中进行。所以,让我们在下一节中了解如何操作。

创建自定义 HTML head

HTML<head> 元素包含 <title>, <style>, <link><meta> 元素。手动添加这些元素可能是一项繁琐的任务。因此,Nuxt 在你的应用程序中为你处理这些元素。在第二章 “Nuxt 入门” 中,你了解到 Nuxt 会从 JavaScript 对象(用花括号 {} 括起来)中的数据为你生成这些元素,这些数据写在 Nuxt 配置文件中,如下所示:

// nuxt.config.js
export default {
  head: {
    title: '默认标题',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'parent' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  }
}

在本主题中,我们对 Nuxt 配置文件中的 meta 块以及 /pages/ 目录中的页面感兴趣。Nuxt 使用 Vue Meta 插件来管理这些 meta 属性。因此,要理解它在 Nuxt 中是如何工作的,我们首先应该理解 Vue Meta 在传统的 Vue 应用程序中是如何工作的。

Vue Meta 简介

Vue Meta 是一个 Vue 插件,用于在 Vue 中管理和创建具有内置响应式的 HTML 元数据。你只需要在任何 Vue 组件中添加 metaInfo 这个特殊的属性,它就会自动渲染成 HTMLmeta 标签,如下所示:

// Component.vue
export default {
  metaInfo: {
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' }
    ]
  }
}

上面的 JavaScript 代码块将会渲染成你页面中的以下 HTML 标签:

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

有关 Vue Meta 的更多信息,请访问 https://vue-meta.nuxtjs.org/。

你可以看到,你所需要做的只是在一个 JavaScript 对象中提供元数据。现在,让我们安装它并学习如何为 Vue 应用程序配置它。

安装 Vue Meta

像所有其他的 Vue 插件一样,你可以通过以下步骤安装 Vue Meta 并将其连接到你的 Vue 应用程序:

  1. 通过 npm 安装 Vue Meta

    $ npm i vue-meta

    或者,你也可以通过 CDN 使用 <script> 元素安装它,如下所示:

    <script src="https://unpkg.com/vue-meta@1.5.8/lib/vue-meta.js"></script>
  2. 如果你正在编写 ES6 JavaScript 应用程序,请在你的主应用程序文件中导入 VueVue Router 以及 Meta

    //main.js
    import Vue from 'vue'
    import Router from 'vue-router'
    import Meta from 'vue-meta'
    Vue.use(Router)
    Vue.use(Meta)
    export default new Router({
      //...
    })
  3. 然后,你可以在任何 Vue 组件中使用它,如下所示:

    // app.vue
    var { data } = await axios.get(...)
    export default {
      metaInfo () {
        return {
          title: 'Nuxt',
          titleTemplate: '%s | My Awesome Webapp',
          meta: [
            { vmid: 'description', name: 'description', content: 'My Nuxt portfolio' }
          ]
        }
      }
    }

在这个例子中,因为我们使用 axios 异步获取数据,所以我们必须使用 metaInfo 方法从异步数据中注入 meta 信息,而不是使用 metaInfo 属性。你甚至可以使用 titleTemplate 选项为你的页面标题添加一个模板,就像前面的例子一样。接下来,我们将创建一个使用这个插件的简单 Vue 应用程序,以便你可以更全面地了解如何使用它。

在 Vue 应用中使用 Vue Meta 创建元数据

通常情况下,我们可以在一个单独的 HTML 页面上启动并运行一个 Vue 应用。让我们开始吧:

  1. <head> 标签中包含 CDN 链接:

    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <script src="https://unpkg.com/vue-meta@1.5.8/lib/vue-meta.js"></script>
  2. <script> 标签中创建以下包含元数据的组件:

    const About = {
      name: 'about',
      metaInfo: {
        title: 'About',
        titleTemplate: null,
        meta: [
          { vmid: 'description', name: 'description', content: 'About my Nuxt...' }
        ]
      }
    }
    const Contact = {
      name: 'contact',
      metaInfo: {
        title: 'Contact',
        meta: [
          { vmid: 'description', name: 'description', content: 'Contact me...' }
        ]
      }
    }
  3. 然后,在根实例中添加默认的元数据:

    const app = new Vue({
      metaInfo: {
        title: 'Nuxt',
        titleTemplate: '%s | My Awesome Webapp',
        meta: [
          { vmid: 'description', name: 'description', content: 'My Nuxt portfolio' }
        ]
      },
      router
    }).$mount('#app')

    请注意,我们可以通过简单地在子组件的 titleTemplate 选项中添加 null 来覆盖组件中的默认元模板,就像前面的 About 组件一样。

    你可以在我们的 GitHub 仓库的 /chapter-4/vue/vuemeta/basic.html 中找到这个示例应用。

在这个例子中,由于我们没有使用 axios 异步获取数据,我们可以直接使用 metaInfo 属性,而不是使用 metaInfo 方法来注入包含异步数据的元信息。然后,当你导航到你刚刚创建的路由时,你将在浏览器中看到页面标题和元信息的变化。在 Vue 应用中使用这个插件非常容易,不是吗?现在,我们将在下一节中了解它在 Nuxt 应用中是如何工作的。

自定义 Nuxt 应用中的默认 meta 标签

Nuxt 应用中创建和自定义元信息更加简单,因为 Nuxt 默认集成了 Vue Meta。这意味着你不需要像在 Vue 应用中那样安装它。你只需要在 Nuxt 配置文件中使用 head 属性来定义应用的默认 <meta> 标签,如下所示:

// nuxt.config.js
head: {
  title: 'Nuxt',
  titleTemplate: '%s | 我的超棒 Web 应用',
  meta: [
    { charset: 'utf-8' },
    { name: 'viewport', content: 'width=device-width, initial-scale=1' },
    { hid: 'description', name: 'description', content: '我的 Nuxt 作品集' }
  ]
}

然而,NuxtVue 应用的区别在于,在 Nuxt 中必须使用 hid 键,而在 Vue 中使用 vmid。为了防止在子组件中定义元标签时出现重复,你应该始终为你的元素使用 hid。另外,请注意 metaInfo 键只在 Vue 中使用,而在 Nuxt 中使用 title 键来添加我们的元信息。

这就是为你的 Nuxt 应用添加和自定义标题和元标签的方法。然而,它们是全局添加的,这意味着它们会应用到你的应用中的所有页面。那么,如何在 Nuxt 配置文件中专门为某个页面添加元信息并覆盖全局的元信息呢?让我们在下一节中找到答案。

为 Nuxt 页面创建自定义 meta 标签

如果您想为特定页面添加自定义元标签或覆盖 Nuxt 配置文件中的默认元标签,只需在该特定页面上直接使用 head 方法,该方法将返回一个包含 titlemeta 选项数据的 JavaScript 对象,如下所示:

// pages/index.vue
export default {
  head () {
    return {
      title: 'Hello World!',
      meta: [
        { hid: 'description', name: 'description', content: 'My Nuxt portfolio' }
      ]
    }
  }
}

然后,您将获得此页面的以下输出:

<title data-n-head="true">Hello World! | My Awesome Webapp</title>
<meta data-hid="description" name="description" content="My Nuxt portfolio" data-n-head="true">

您可以在我们 GitHub 仓库的 /chapter-4/nuxtuniversal/view/html-head/ 中找到这个示例应用程序。

就是这样。这就是关于 Nuxt 中应用程序模板和 HTML head 的全部内容。Nuxt 视图的下一个内部层是布局,我们将在下一节中指导您如何创建自定义布局。让我们开始吧。

创建自定义布局

布局是你页面和组件的骨干。你可能希望在你的应用中拥有多种不同的布局。有一个名为 default.vue 的布局,当你使用 npx create-nuxt-app 脚手架工具安装你的应用时,它会自动在 /layouts/ 目录下生成。就像应用模板一样,你可以修改这个默认布局或者创建你自己的自定义布局。

修改默认布局

默认布局始终用于没有特定或自定义布局的页面。如果你前往 /layouts/ 目录并打开此布局,你应该看到其中只有三行代码用于渲染你的页面组件:

// layouts/default.vue
<template>
  <nuxt/>
</template>

让我们修改这个默认布局,如下所示:

// layouts/default.vue
<template>
  <div>
    <div>...在此处添加导航栏...</div>
    <nuxt/>
  </div>
</template>

你应该看到你添加的任何内容——例如,应用程序中所有页面的导航栏。请注意,无论是修改此布局还是创建新布局,请确保在希望 Nuxt 导入页面组件的位置放置 <nuxt/> 组件。我们将在下一节探讨如何创建自定义布局。

创建新的自定义布局

有时候,对于更复杂的应用程序,我们需要不止一个布局。对于某些页面,我们可能需要不同的布局。对于这种情况,你需要创建自定义布局。你可以使用 .vue 文件创建自定义布局,并将它们放在 /layouts/ 目录下。

以下是一个示例:

// layouts/about.vue
<template>
  <div>
    <div>...add an about navigation bar here....</div>
    <nuxt/>
  </div>
</template>

然后,你可以在页面组件中使用 layout 属性来将此自定义布局分配给该页面,如下所示:

// pages/about.vue
export default {
  layout: 'about'
  // 或者
  layout (context) {
    return 'about'
  }
}

现在,Nuxt 将使用 /layouts/about.vue 文件作为此页面组件的基础布局。但是,对于显示未知和无效路由的错误页面的布局又该如何处理呢?让我们在下一节中了解它是如何实现的。

创建自定义错误页面

每个你安装的 Nuxt 应用都带有一个默认的错误页面,该页面存储在 @nuxt 包的 /node_modules/ 目录下,Nuxt 使用它来显示错误,例如 404500 等等。你可以通过在 /layouts/ 目录下添加一个 error.vue 文件来定制它。让我们通过以下步骤来了解如何实现这一点:

  1. /layouts/ 目录下创建一个自定义错误页面,如下所示:

    // layouts/error.vue
    <template>
      <div>
        <h2 v-if="error.statusCode === 404">页面未找到</h2>
        <h2 v-else>发生了一个错误</h2>
        <nuxt-link to="/">首页</nuxt-link>
      </div>
    </template>
    <script>
    export default {
      props: ['error']
    }
    </script>

    请注意,错误页面是一个页面组件。起初,这似乎有些违反直觉和令人困惑,因为它被放置在 /layouts/ 目录下而不是 /pages/ 目录下。然而,即使它位于 /layouts/ 目录下,也应该将其视为一个页面。

  2. 就像其他的页面组件一样,你可以为这个错误页面创建一个自定义布局,如下所示:

    // layouts/layout-error.vue
    <template>
      <div>
        <h1>Error!</h1>
        <nuxt/>
      </div>
    </template>
  3. 然后,只需将 layout-error 添加到错误页面的 layout 选项中:

    // layouts/error.vue
    <script>
    export default {
      layout: 'layout-error'
    }
    </script>
  4. 现在,如果你导航到以下任何未知路由,Nuxt 将调用这个自定义错误页面和自定义错误布局:

    • /company

    • /company/careers

    • /company/careers/london

    • /users/category/subject

    • /users/category/subject/type

你可以在我们的 GitHub 仓库的 /chapter-4/nuxtuniversal/view/custom-layouts/404/ 中找到这个 404 示例。

就是这样。以上就是关于 Nuxt 中布局的全部内容。Nuxt 视图的下一个内部层是页面,你将在下一节学习如何为你的应用创建自定义页面。所以,请继续阅读。

创建自定义页面

页面是 Nuxt 视图层的一部分,就像我们已经介绍过的应用程序模板、HTML head 和布局一样。/pages/ 目录是您存储页面的地方。您将花费大部分时间在这个目录中创建 Nuxt 应用程序的页面。然而,创建页面并不是什么新鲜事——我们在上一节的 /layouts/ 目录中创建了一个简单的错误页面,并且在学习如何为我们的应用程序创建自定义路由时创建了许多页面。因此,当您想为特定路由创建自定义页面时,只需在 /pages/ 目录中创建一个 .vue 文件即可;例如,我们可以创建以下页面:

pages/
--| index.vue
--| about.vue
--| contact.vue

然而,创建自定义页面需要的不仅仅是这些。我们需要了解 Nuxt 提供的页面上的属性和函数。尽管页面是 Nuxt 应用程序开发的重要组成部分,但在 Vue 应用程序开发中并没有强调这一点,但它们与 Vue 组件密切相关,并且工作方式与组件略有不同。因此,要创建并充分使用一个页面,我们首先需要了解 Nuxt 中的页面是什么。让我们来了解一下。

理解页面

在本质上,一个页面就是一个 Vue 组件。它与标准的 Vue 组件的区别在于 Nuxt 专门添加的属性和函数。我们使用这些特殊的属性和函数在渲染页面之前设置或获取数据,如下所示:

<template>
  <p>{{ message }}!</p>
</template>

<script>
export default {
  asyncData (context) {
    return { message: 'Hello World' }
  }
}
</script>

在上面的例子中,我们使用了一个名为 asyncData 的函数来设置 message 键中的数据。asyncData 函数是你在 Nuxt 应用中会看到并经常使用的函数之一。让我们深入了解那些专门为 Nuxt 页面设计的属性和函数。

asyncData 方法

asyncData 方法是页面组件中最重要的函数。Nuxt 总是在初始化页面组件之前调用此函数。这意味着每次你请求一个页面时,这个函数都会在页面渲染之前首先被调用。它将 Nuxt 上下文作为第一个参数,并且可以异步使用,如下所示:

<h1>{{ title }}</h1>
<script>
import axios from 'axios'

export default {
  async asyncData ({ params }) {
    let { data } = await axios.get(
      'https://jsonplaceholder.typicode.com/posts/' + params.id
    )
    return { title: data.title }
  }
}
</script>

在这个例子中,我们使用 ES6 的解构赋值语法来解包 Nuxt 上下文中打包的属性,而这个特定的属性是 params。换句话说,{ params }context.params 的简写。我们也可以使用解构赋值语法来解包来自 axios 异步结果中的 data 属性。请注意,如果你在页面组件的 data 函数中设置了 data,它将始终与来自 asyncData 的数据合并。然后,合并后的数据可以在 <template> 块中使用。让我们创建一个简单的例子来演示 asyncData 如何与 data 函数合并:

<h1>{{ title }}</h1>
<script>
export default {
  data () {
    return { title: 'hello world!' }
  },
  async asyncData (context) {
    return { title: 'hey nuxt!' }
  }
}
</script>

你看到了两个从 dataasyncData 方法返回的数据对象,但是你将得到的上述代码的输出是:

<h1>hey nuxt!</h1>

你可以看到,如果 asyncData 函数和 data 函数都使用相同的键,那么来自 asyncData 函数的数据将始终替换 data 函数中的数据。另请注意,我们不能在 asyncData 方法中使用 this 关键字,因为这个方法是在页面组件初始化之前被调用的。因此,你不能使用 this.title = data.title 来更新数据。我们将在第八章 “添加服务端框架” 中更详细地介绍 asyncData

fetch 方法

fetch 方法的工作方式与 asyncData 方法相同,不同之处在于它在 Vuecreated 生命周期钩子之后被调用——换句话说,在组件初始化之后。与 asyncData 方法类似,它也可以异步使用;例如,你也可以使用它来设置页面组件中的数据:

// pages/users/index.vue
<li v-for="user in users" v-bind:key="user.id">
  <nuxt-link :to="`users/${user.id}`">
    {{ user.name }}
  </nuxt-link>
</li>
<script>
import axios from 'axios'
export default {
  data () {
    return { users: [] }
  },
  async fetch () {
    let { data } = await axios.get(
      'https://jsonplaceholder.typicode.com/users'
    )
    this.users = data
  }
}
</script>

请注意,data 方法必须与 fetch 方法一起使用才能设置数据。由于它在页面组件初始化之后被调用,我们可以使用 this 关键字来访问 data 方法中的对象。我们也可以使用此方法从页面组件设置 Vuex store 中的数据,如下所示:

// pages/posts/index.vue
<li v-for="post in $store.state.posts" v-bind:key="post.id">
  <nuxt-link :to="`posts/${post.id}`">
    {{ post.title }}
  </nuxt-link>
</li>
<script>
import axios from 'axios'
export default {
  async fetch () {
    let { data } = await axios.get(
      'https://jsonplaceholder.typicode.com/posts'
    )
    const { store } = this.$nuxt.context
    store.commit('setPosts', data)
  }
}
</script>

我们将在第 10 章 “添加 Vuex Store” 中更详细地介绍 fetch 方法和 Vuex store

你可以在我们的 GitHub 仓库的 /chapter-4/nuxtuniversal/view/custom-pages/fecth-method/ 路径下找到本节中的上述代码。

head 方法

head 方法用于设置页面的 <meta> 标签,我们之前在 “创建自定义 HTML head 部分” 中已经介绍过。它也可以与 /components/ 目录中的组件一起使用。

layout 属性

布局键(或属性)用于指定页面要使用的布局,该布局位于 /layouts/ 目录下,我们之前在 “创建自定义布局” 部分中已经介绍过。

loading 属性

加载属性允许您禁用默认的加载进度条或在特定页面上设置自定义加载条。我们在第二章 “Nuxt.js 入门” 中简要介绍过它,所以我们知道可以在 Nuxt 配置文件中配置全局默认的加载组件,如下所示:

// nuxt.config.js
export default {
  loading: {
    color: '000000'
  }
}

然而,由于我们是在 localhost 上进行开发,并且通常不需要太多时间来处理数据,我们通常无法看到这个加载条的实际效果。为了演示这个加载组件的工作方式和外观,让我们通过延迟组件中数据的加载时间来演示一下(但请注意,这个演示不应该在生产环境中使用):

  1. /pages/ 目录下创建一个 index.vue 页面,代码如下:

    // pages/index.vue
    <template>
      <div class="container">
        <p>Hello {{ name }}!</p>
        <NuxtLink to="/about">
          Go to /about
        </NuxtLink>
      </div>
    </template>
    <script>
    export default {
      asyncData () {
        return new Promise((resolve) => {
          setTimeout(function () {
            resolve({ name: 'world' })
          }, 1000)
        })
      }
    }
    </script>
  2. /pages/ 目录下创建另一个名为 about.vue 的页面,代码如下:

    // pages/about.vue
    <template>
      <div class="container">
        <p>About Page</p>
        <NuxtLink to="/">
          Go to /
        </NuxtLink>
      </div>
    </template>
    
    <script>
    export default {
      asyncData () {
        return new Promise((resolve) => {
          setTimeout(function () {
            resolve({})
          }, 1000)
        })
      }
    }
    </script>

    在这两个页面中,我们使用 setTimeout 将数据响应延迟了 1 秒。因此,当在页面之间导航时,您应该在请求的页面加载之前看到黑色的加载条出现在页面顶部。

    您可以在我们的 GitHub 仓库的 /chapter-4/nuxtuniversal/view/custom-pages/loading-page/ 中找到这个示例。

  3. 当然,我们可以通过在 /components/ 目录下创建一个组件来创建自定义的加载条或图层。以下是一个示例:

    // components/loading.vue
    <template>
      <div v-if="loading" class="loading-page">
        <p>Loading...</p>
      </div>
    </template>
    <script>
    export default {
      data () {
        return { loading: false }
      },
      methods: {
        start () { this.loading = true },
        finish () { this.loading = false },
      }
    }
    </script>
    <style scoped>
    .loading-page {
      position: fixed;
      //...
    }
    </style>

    请注意,自定义加载组件中必须暴露 startfinish 方法,以便 Nuxt 可以在路由更改时(调用 start 方法)和加载完成时(调用 finish 方法)调用您的组件并使用这些方法。

    因此,在这个组件中,加载元素始终是隐藏的,因为 loading 属性在 data 方法中默认设置为 false。只有在路由更改期间 loading 属性设置为 true 时,加载元素才会变得可见。然后在路由加载完成后,loading 属性再次设置为 false,加载元素又会隐藏起来。

    有关这些方法和其他可用方法的更多信息,请访问 https://nuxtjs.org/api/configuration-loading

  4. 将上述自定义组件的路径包含在 Nuxt 配置文件的 loading 属性中:

    // nuxt.config.js
    export default {
      loading: '~/components/loading.vue'
    }

    您可以在我们的 GitHub 仓库的 /chapter-4/nuxtuniversal/view/custom-pages/loading-global-custom/ 中找到这个示例。

  5. 我们还可以配置特定页面的加载行为,如下所示:

    // pages/about.vue
    export default {
      loading: false
    }
  6. 如果页面上的 loading 键的值为 false,它将停止自动调用 $nuxt.$loading.finish()$nuxt.$loading.start() 方法,这允许您在脚本中手动控制它们,如下所示:

    // pages/about.vue
    <span class="link" v-on:click="goToFinal">
      click here
    </span>
    export default {
      loading: false,
      mounted () {
        setTimeout(() => {
          this.$nuxt.$loading.finish()
        }, 5000)
      },
      methods: {
        goToFinal () {
          this.$nuxt.$loading.start()
          setTimeout(() => {
            this.$router.push('/final')
          }, 5000)
        }
      }
    }
  7. 然后,在 /pages/ 目录下创建 final.vue 页面:

    // pages/final.vue
    <template>
      <div class="container">
        <p>Final Page</p>
        <NuxtLink to="/">
          Go to /
        </NuxtLink>
      </div>
    </template>

在这个示例中,您可以看到可以通过 $nuxt.$loading.finish()$nuxt.$loading.start() 手动控制加载条。在 mounted 方法中,加载条需要 5 秒钟才能完成。当您触发 goToFinal 方法时,加载条会立即启动,并且需要 5 秒钟才能将路由更改为 /final

您可以在我们的 GitHub 仓库的 /chapter-4/nuxtuniversal/view/custom-pages/loading-page/ 中找到这个示例。

transition 属性

transition 属性用于指定页面的过渡效果。你可以使用字符串、对象或函数作为这个键的值,如下所示:

// pages/about.vue
export default {
  transition: ''
  // 或者
  transition: {}
  // 或者
  transition (to, from) {}
}

我们将在本章后面的 “创建自定义过渡效果” 部分深入探讨 transition 属性。

scrollToTop 属性

当您希望嵌套路由中的页面在渲染之前从顶部开始时,可以使用 scrollToTop 键。默认情况下,当您导航到另一个页面时,Nuxt 会滚动到顶部,但在嵌套路由的子页面中,Nuxt 会保持与前一个子路由相同的滚动位置。因此,如果您想告诉 Nuxt 为这些页面滚动到顶部,请将 scrollToTop 设置为 true,如下所示:

// pages/users/_id.vue
export default {
  scrollToTop: true
}

validate 方法

validate 方法是动态路由的验证器,我们已经在 “验证路由参数” 一节中介绍过了。

middleware 属性

middleware 属性用于为页面指定中间件。分配的中间件总是在页面渲染之前执行,如下所示:

// pages/secured.vue
export default {
  middleware: 'auth'
}

在这个例子中,auth 是你将在 /middleware/ 目录下创建的中间件的文件名,如下所示:

// middleware/auth.js
export default function ({ route }) {
  //...
}

我们将在第 11 章 “编写路由中间件和服务端中间件” 中深入介绍中间件。

就这样,你已经完成了关于 Nuxt 视图的各个部分,从应用模板、HTML head 和布局到页面。做得好!我们将在下一章介绍 Vue 组件。但是现在,我们接下来应该看一下在 Nuxt 中创建自定义页面过渡效果,因为过渡效果和页面是紧密相关的,就像你已经被简要介绍过的 page Transition 属性一样。所以,让我们继续本章的最后一个主题,你将学习如何创建自定义过渡效果。