服务器端渲染-Nuxt.js基础

前言

上一篇文章服务器端渲染基础,介绍了各种渲染模式的优缺点,并在最后利用vue.jsNuxt.js,通过一个小案例,体验了现代服务器渲染模式。


Nuxt.js定义

  • Nuxt.js 是一个基于 Vue.js 的服务端渲染应用框架,通过对客户端/服务端基础架构的抽象组织,Nuxt.js主要关注的是应用的UI渲染,可以轻松的实现同构应用
  • 作为客户端/服务端框架,提供了很多有用的特性:
    • 基于 Vue.js
    • 自动代码分层
    • 服务端渲染
    • 强大的路由功能,支持异步数据
    • 静态文件服务
    • ES2015+ 语法支持
    • 打包和压缩 JSCSS
    • HTML 头部标签管理
    • 本地开发支持热加载
    • 集成 ESLint
    • 支持各种样式预处理器: SASSLESSStylus 等等
    • 支持 HTTP/2 推送

Nuxt.js使用范围

Nuxt.js主要在以下几种情况下使用:

  1. 使用Nuxt.js初始化一个全新的项目
  2. 对于已有的node.js服务端项目,直接把Nuxt当做一个中间件集成到Node Web Server
  3. 解决现有Vue.js项目的首屏加载慢、不利于SEO的缺陷,这种情况下要求开发人员对Nuxt掌握程度高,且代码的改动量大,至少改动10%。

创建Nuxt项目

Nuxt.js 提供了两种方式用来创建项目:

手动创建项目,进入项目目录

# 初始化 package.json 文件
yarn init
# 安装 nuxt
yarn add nuxt

package.json文件的scripts中新增:

"scripts": {
    
    
   "dev": "nuxt" //可以通过运行npm run dev来运行nuxt
},

新建pages目录,创建第一个页面pages/index.vue

<template>
  <div>
    <h1>Hello Nuxt.js</h1>
  </div>
</template>

<script>
export default {
    
    
   name: 'home'
}
</script>

<style>

</style>

启动项目

yarn dev

应用在http://localhost:3000上运行,查看在浏览器上是否能正产访问。

注意:Nuxt.js 会监听pages目录中的文件更改,因此在添加新页面时无需重新启动应用程序。

路由

普通路由

Vue.js不同的是,Nuxt.js不需要开发者在项目中显式地定义vue-router的路由规则,Nuxt.js会依据pages目录中的所有*.vue文件自动生成vue-router模块的路由配置,找到文件夹下的index.vue并将它作为此文件夹根路径的组件。

pages的目录结构如下:

pages/
--| user/
-----| index.vue
-----| info.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/info',
            component: 'pages/user/info.vue'
        }
    ]
}

路由导航

Nuxt.js提供了路由组件nuxt-link用于页面之间的跳转,它的作用和 router-link 一致, 通过 to 属性指定目标地址,默认渲染成带有正确链接的a标签,可以通过配置 tag 属性生成别的标签。

<nuxt-link to="/">跳转到首页</nuxt-link>

同样也支持编程式路由导航,使用方法也和Vue.js编程式导航一致

<button @click="onClick">跳转到首页</button>

methods: {
    
    
  onClick() {
    
    
     this.$router.push('/');
  }
}		

还支持支持使用<a></a> 标签进行页面跳转,但这种方式会刷新页面,向服务器端发送请求,故不推荐。

嵌套路由

Nuxt.js提供了三种实现嵌套路由的方式。

  • 通过 vue-router 的子路由创建 Nuxt.js 应用的嵌套路由
  • nuxt.config.js中通过extendRoutes自定义路由规则
  • 使用Nuxt.js依据pages目录中的所有*.vue文件自动生成vue-router模块的路由配置规则,但需要满足以下两个条件:
    • 添加一个 .vue 文件,同时添加一个与该文件同名的目录用来存放它的子视图组件
    • 在父组件(.vue文件) 内增加用于显示子视图内容(相当于vue.jsrouter-view

如下图中的父组件students.vue,它的子组件都存放在与它同名的students目录下

在这里插入图片描述

动态路由

通过extendRoutes设置的自定义路由规则,动态路由匹配规则同vue的动态路由匹配,而在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件或目录。

目录结构如下:

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

Nuxt.js 生成对应的路由配置表如下:

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

自定义路由配置

base用于在nuxt.config.js配置应用的根路径,例如:

//nuxt.config.js

module.exports = {
    
    
  router: {
    
    
     base: '/app'  //默认路由改为http://localhost:3000/app/
  }
}

extendRoutes扩展Nuxt.js创建的路由或自定义路由配置规则,下面的例子配置自定义路由表规则

//nuxt.config.js

module.exports = {
    
    
  router: {
    
    
    extendRoutes(routes, resolve) {
    
    
      routes.splice(0);//清除nuxtjs根据Pages目录生成的默认路由
      routes.push(...[
        {
    
    
          path: '/',
          component: resolve(__dirname, 'pages/layout/'),
          children: [
            {
    
    
              path: '', //默认子路由
              name: 'home',
              component: resolve(__dirname, 'pages/home/')
            },
            {
    
    
              path: '/login',
              name: 'login',
              component: resolve(__dirname, 'pages/login/')
            }
          ]
        }
      ]); 
    }
  }
}

视图

Nuxt.js视图的组成部分如下图所示:

在这里插入图片描述

模板

Nuxt.js默认模板为:

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

src 文件夹下(默认是应用根目录)创建一个 app.html 的文件就可以定制化默认的 html 模板。

布局

根据Nuxt.js的目录规则,在一个应用中若无额外的配置项,布局组件必须写在布局目录layouts中。

  • 默认布局

通过 layouts/default.vue 文件来扩展应用的默认布局,此文件必须添加 <nuxt/> 组件用于显示页面的主体内容。

<template>
  <div>
    <ul>
      <li>
        <!--相当于router-link-->
        <nuxt-link to="/">首页</nuxt-link>
      </li>
      <li>
        <nuxt-link to="/about">关于</nuxt-link>
      </li>
    </ul>
    <!--页面路由视图,相当于router-view-->
    <nuxt></nuxt>
  </div>
</template>
  • 自定义布局

layouts 目录中的每个文件 (顶级) 都将创建一个可通过页面组件中的 layout 属性访问的自定义布局。

例如创建一个 博客布局layouts/blog.vue:

<template>
  <div>
    <div>我的博客导航栏在这里</div>
    <nuxt />
  </div>
</template>

然后必须在相应的页面中通过layout指定此页面引用的自定义布局:

<template>
   ···
</template>
<script>
  export default {
    
    
    layout: 'blog'
  }
</script>
  • 错误页面

Nuxt.js规定 layouts 根目录下的所有文件都属于个性化布局文件,除了layouts/error.vue(不需要包含 <nuxt/> 标签),此文件放在 layouts 文件夹中, 但它是一个 页面,用于定制化错误页面(404、500页面)。

例如一个定制化的404页面:

template>
  <div class="container">
    <h1 v-if="error.statusCode === 404">页面不存在</h1>
    <h1 v-else>应用发生错误异常</h1>
    <nuxt-link to="/">首 页</nuxt-link>
  </div>
</template>

<script>
  export default {
    
    
    props: ['error'],
    layout: 'blog' // 为错误页面指定自定义的布局
  }
</script>

页面

Nuxt.js的页面实际上是Vue组件,并在这些组件基础上添加了一些特殊的配置项

<template>
  <div>
    <h1>{
    
    {
    
     title1 }}</h1>
    <ul>
      <li v-for="item in list" :key="item.id">
        {
    
    {
    
     item.title }}: {
    
    {
    
     item.content }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
    
    
  name: "Home",
  //Nuxt.js中的钩子函数,专门用于获取页面服务端渲染的数据
  async asyncData() {
    
    
    ...
  }
};
</script>

数据

Nuxt.js 增加了一个 asyncData 方法,可以在设置组件的数据之前能异步获取或处理数据。

只能在页面组件中使用,不能用于页面组件的子组件
asyncData方法内不能使用this,因为它是在页面组件初始化之前调用

调用时机:

  • asyncData方法会在页面组件加载之前被调用
  • 服务端渲染期间、客户端路由更新之前都会调用asyncData

参数及返回值:

  • asyncData的第一个参数被设定为当前页面的上下文对象(包括request / response / params / query / store)
  • Nuxt.js会将asyncData返回的数据和组件data方法返回数据融合到一起给组件使用

Nuxt.js 提供了几种不同的方法来使用 asyncData 方法:

  • 使用 asyncawait
<template>
  ...
</template>

<script>
export default {
    
    
  async asyncData({
    
     params }) {
    
    
    const {
    
     data } = await axios.get(`https://my-api/posts/${
    
    params.id}`)
    return {
    
     title: data.title }
  }
}
</script>
  • 返回一个 Promise, nuxt.js 会等待该Promise被解析之后才会设置组件的数据,从而渲染组件
<template>
  ...
</template>

<script>
export default {
    
    
  asyncData({
    
     params }) {
    
    
    return axios.get(`https://my-api/posts/${
    
    params.id}`).then(res => {
    
    
      return {
    
     title: res.data.title }
    })
  }
}
</script>

文章列表

服务器端渲染基础
服务器端渲染-Nuxt.js基础
服务器端渲染-Nuxt.js综合案例
服务器端渲染-Nuxt.js综合案例发布部署
服务器端渲染-Vue SSR搭建

猜你喜欢

转载自blog.csdn.net/weixin_41269811/article/details/112341863