Nuxt详解+案例

117 阅读3分钟

1. Nuxt.js 概述

1.1 我们一起做过的SPA

SPA(single page web application)单页 Web 应用,Web 不再是一张张页面,而是一个整体的应用,一个由路由系统、数据系统、页面(组件)系统等等,组成的应用程序。

我们之前学习的Vue就是SPA中的佼佼者。

SPA 应用广泛用于对SEO要求不高的场景中

image.png

1.2 什么是SEO

SEO:搜索引擎优化(Search Engine Optimization), 通过各种技术(手段)来确保,我们的Web内容被搜索引擎最大化收录,最大化提高权重,最终带来更多流量。

非常明显,SPA程序不利于SEO

image.png

SEO解决方案:提前将页面和数据进行整合

  • 前端:采用SSR
  • 后端:页面静态化 (freemarker 、thymeleaf、velocity)

1.3 什么是SSR技术

服务端渲染(Server Side Render),即:网页是通过服务端渲染生成后输出给客户端。

在SSR中,前端分成2部分:前端客户端、前端服务端 前端服务端,用于发送ajax,获得数据 前端客户端,用于将ajax数据和页面进行渲染,渲染成html页面,并响应给调用程序(浏览器、爬虫)

image.png

如果爬虫获得html页面,就可以启动处理程序,处理页面内容,最终完成SEO操作。

1.4 SPA和SSR对比

image.png

1.5 什么是Nuxt.js

  • Nuxt.js 是一个基于 Vue.js 的通用应用框架。

    • Nuxt支持vue的所有功能,此类内容为前端客户端内容。
    • Nuxt特有的内容,都是前端服务端内容。
  • 通过对客户端/服务端基础架构的抽象组织,Nuxt.js 主要关注的是应用的 UI 渲染。

  • Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所需要的各种配置。

2 入门案例

2.1 create-nuxt-app 介绍

Nuxt.js 提供了脚手架工具 create-nuxt-app

create-nuxt-app 需要使用 npx

npx 命令为 NPM版本5.2.0默认安装组件

2.2 安装

npx create-nuxt-app <project-name>

例如 npx create-nuxt-app demo_nuxt02

image.png

nuxtjs改善

image.png

2.3 启动

npm run dev

image.png

2.4 访问

http://localhost:3000

image.png

3. 目录结构

3.1 目录

image.png

image.png

3.2 别名

  • assets 资源的引用:~ 或 @
// HTML 标签
<img src="~assets/13.jpg" style="height:100px;width:100px;" alt="">
<img src="~/assets/13.jpg" style="height:100px;width:100px;" alt="">
<img src="@/assets/13.jpg" style="height:100px;width:100px;" alt="">

// CSS
background-image: url(~assets/13.jpg);
background-image: url(~/assets/13.jpg);
background-image: url(@/assets/13.jpg);
  • static 目录资源的引用:/ 直接引用
//html标签
<img src="/12.jpg" style="height:100px;width:100px;" alt="">

//css
background-image: url(/12.jpg);
  • 实例
<template>
  <div>
    <!-- 引用 assets 目录下经过 webpack 构建处理后的图片 -->
    <img src="~assets/13.jpg" style="height:100px;width:100px;" alt="">

    <!-- 引用 static 目录下的图片 -->
    <img src="/12.jpg" style="height:100px;width:100px;" alt="">

    <!-- css -->
    <div class="img1"></div>
    <div class="img2"></div>
  </div>
</template>

<script>
export default {

}
</script>

<style>
  .img1 {
    height: 100px;
    width: 100px;
    background-image: url(~assets/13.jpg);
    background-size: 100px 100px;
    display: inline-block;
  }
  .img2 {
    height: 100px;
    width: 100px;
    background-image: url(/12.jpg);
    background-size: 100px 100px;
    display: inline-block;
  }
</style>

4 路由

4.1 路由概述

  • Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。
  • 要在页面之间切换路由,我们建议使用 标签。

image.png

4.2 基础路由

  • 自动生成基础路由规则

image.png

  • 实例
情况1:访问路径,由pages目录资源的名称组成(目录名称、文件的名称)
  - 资源位置: ~/pages/user/one.vue
  - 访问路径:http://localhost:3000/user/one


情况2:每一个目录下,都有一个默认文件 index.vue
  - 资源位置: ~/pages/user/index.vue
  - 访问路径:http://localhost:3000/user
  • 思考:/user 可以匹配几种文件?

    • pages/user.vue 文件 【优先级高】
    • pages/user/index.vue 文件

4.3 动态路由

  • 在 Nuxt.js 里面定义带参数的动态路由,需要创建对应的以下划线作为前缀的 Vue 文件 或 目录。

image.png

  • 实例1:获得id值,创建资源 user/_id.vue
<template>
  <div>
    查询详情 {{this.$route.params.id}}
  </div>
</template>

<script>
export default {
  transition: 'test',
  mounted() {
    console.info(this.$route)
  },
}
</script>

<style>

</style>

4.4 动态命名路由

  • 路径 /news/123 匹配_id.vue还是_name.vue ?

image.png

  • 我们可以使用解决以上问题

  • 通过name 确定组件名称:“xxx-yyy”

  • 通过params 给对应的参数传递值

<nuxt-link :to="{name:'news-id',params:{id:1002}}">第2新闻</nuxt-link>
<nuxt-link :to="{name:'news-name',params:{name:1003}}">第3新闻</nuxt-link>

4.5 默认路由

image.png

  • 404页面,可以采用 _.vue进行处理

4.6 嵌套路由(懂就👌)

  • 创建嵌套子路由,你需要添加一个 父组件Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。

    • 要求:父组件 使用 显示子视图内容
pages/
--| book/						//同名文件夹
-----| _id.vue
-----| index.vue
--| book.vue					//父组件
  • 步骤1:编写父组件 pages/child/book.vue
<template>
  <div>
      <nuxt-link to="/child/book/list">书籍列表</nuxt-link> |
      <nuxt-link to="/child/book/123">书籍详情</nuxt-link> |
      <hr>
      <nuxt-child />
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>
  • 步骤2:编写子组件 pages/child/book/list.vue
<template>
  <div>书籍列表</div>
</template>

<script>
export default {

}
</script>

<style>

</style>
  • 步骤3:编写子组件 pages/child/book/_id.vue
<template>
  <div>书籍详情{{$route.params.id}} </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

4.7 过渡动效(了解就👌)

4.7.1 全局过渡动效设置

  • Nuxt.js 默认使用的过渡效果名称为 page

    • .page-enter-active样式表示进入的过渡效果。
    • .page-leave-active样式表示离开的过渡效果。
  • 步骤1:创建 assets/main.css,编写如下内容:

.page-enter-active, .page-leave-active {
  transition: opacity .5s;
}
.page-enter, .page-leave-active {
  opacity: 0;
}
  • 步骤2:nuxt.config.js 引入main.css文件
module.exports = {
  css: [
    'assets/main.css'
  ]
}

4.7.1 自定义动画 如果想给某个页面自定义过渡特效的话,只要在该页面组件中配置 transition 字段即可:

步骤1:在全局样式 assets/main.css 中添加名称为test的过渡效果

.test-enter-active, .test-leave-active {
  transition: all 2s;
  font-size:12px;
}
 .test-enter, .test-leave-active {
  opacity: 0;
  font-size:40px;
}
  • 步骤2:需要使用特效的vue页面编写如下:
export default {
  transition: 'test'
}

5. 视图

5.1 默认模板(了解👌)

  • 定制化默认的 html 模板,只需要在应用根目录下创建一个 app.html 的文件。

  • 默认模板:

<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  </body>
</html>
  • 修改模板,对低版本IE浏览器进行支持(兼容IE浏览器)
<!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_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
    {{ APP }}
  </body>
</html>

5.2 默认布局

5.2.1 布局概述

  • 布局:Nuxt.js根据布局,将不同的组件进行组合。

  • 模板:html页面,是布局后所有组件挂载的基础。

image.png

5.2.2 布局分析

  • layouts/default.vue 默认布局组件
    • 访问路径根据路由,确定执行组件
    • 组件具体显示的位置,有布局来确定

image.png

5.2.3 公共导航

  • 修改 layouts/default.vue
<template>
  <div>
    <nuxt-link to="/">首页</nuxt-link> |
    <nuxt-link to="/user/login">登录</nuxt-link> |
    <nuxt-link to="/user/123">详情</nuxt-link> |
    <nuxt-link to="/about">默认页</nuxt-link> |
    <nuxt-link to="/nuxt/async">async</nuxt-link> |
    <hr/>
    <Nuxt />
  </div>
</template>

5.3 自定义布局

在layouts目录下创建组件:layouts/blog.vue

<template>
	<div>
        开头<br/>
        <nuxt/>
        结束<br/>
    </div>
  
</template>

<script>
export default {

}
</script>

<style>

</style>
  • 在需要的视图中使用 blog布局
<script>
export default {
  layout: 'blog'
  //...
}
</script>

image.png

5.4 错误页面

  • 编写layouts/error.vue页面,实现个性化错误页面
<template>
  <div>
    <div v-if="error.statusCode == 404">
      404 页面不存在 {{error.message}}
    </div>
    <div v-else>
      应用程序错误
    </div>
    <nuxt-link to="/">首 页</nuxt-link>
  </div>
</template>

<script>
export default {
  props: ['error']
}
</script>

<style>

</style>
  • 解决问题: 404 、500、连接超时(服务器关闭)
  • 总结:所学习的技术中,有2种方式处理错误页面
    • 方式1:默认路径,_.vue (先执行)
    • 方式2:错误页面,~/layouts/error.vue

5.5 Nuxt组件特殊配置

  • 页面组件实际上是 Vue 组件,只不过 Nuxt.js 为这些组件添加了一些特殊的配置项

image.png

5.5.1 模板代码

<template>
  <h1 class="red">Hello {{ name }}!</h1>
</template>

<script>
export default {
	//异步处理数据, 每次加载之前被调用
  asyncData (context) {
    // called every time before loading the component
    return { name: 'World' }
  },	
	//用于在渲染页面之前获取数据填充应用的状态树(store)
  fetch () {
    // The fetch method is used to fill the store before rendering the page
  },
	//配置当前页面的 Meta 标签
  head: {
    // Set Meta Tags for this Page
  },
  // and more functionality to discover
  ...
}
</script>

<style>
.red {
  color: red;
}
</style>

5.5.2 head html模板代码

<html>
<head>
	<meta charset="UTF-8" />
	<title>我是标题</title>
	<link rel="stylesheet" type="text/css" href="css外部文件"/>
	<script src="js外部文件" type="text/javascript" charset="utf-8"></script>
</head>
<body>
</body>
</html>
  • 通过nuxt提供head属性,可以给单个也是设置:标题、外部css、外部js 等内容。

image.png

<template>
  <div>
    详情页 {{$route.params.id}} <br/>

    <div class="bg2"></div>
    <div class="bg3"></div>

  </div>
</template>

<script>
export default {
  head: {
    title: '详情页',
    link: [
      {rel:'stylesheet',href:'/style/img.css'},....
    ],
    script: [
      { type: 'text/javascript', src: '/js/news.js' }
    ]
  }
}
</script>

<style>
  .bg2 {
    background-image: url('~static/img/2.jpg');
    width: 300px;
    height: 300px;
    background-size: 300px;
  }
</style>