特性

  • 基于 Vue.js
  • Vue、Vue Router、Vuex、Vue SSR
  • 自动代码分层
  • 服务端渲染
  • 强大的路由功能,支持异步数据
  • 静态文件服务
  • ES2015+ 语法支持
  • 打包和压缩 JS 和 CSS
  • HTML 头部标签管理
  • 本地开发支持热加载
  • 集成 ESLint
  • 支持各种样式预处理器: SASS、LESS、 Stylus 等等
  • 支持 HTTP/2 推送

Nuxt.js 框架是如何运作的

Nuxt.js 集成了以下组件/框架,用于开发完整而强大的 Web 应用:
- Vue.js
- Vue Router
- Vuex
- Vue Server Renderer
压缩并 gzip 后,总代码大小为:57kb(如果使用了 Vuex 特性的话为 60kb)
。另外,Nuxt.js 使用Webpack和vue-loader、babel-loader来处理代码的自动化构建工作(如打包、代码分层、压缩等等)。

2、初始化NuxtJS项目

Nuxt.js的使用方式

  • 初始化项目
  • 已有的Node.js服务端项目
  • 直接把Nuxt当作一个中间件集成到 Node Web Server 中
  • 现有的Vue.js项目
  • 非常熟悉Nuxt.js
  • 至少百分之10的代码改动

创建项目

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

  • 使用 create-nuxt-app 脚手架工具
  • 手动创建

为了让大家有一个更好的学习效果,这里我们建议先通过手动创建的方式来学习 Nuxt,熟悉了Nuxt 的基本能使用之后,我们会在后面的综合案例中学习如何使用 create-nuxt-app 创建项目。
(1)准备

# 创建示例项目
mkdir nuxt-app-demo
# 进入示例项目目录中
cd nuxt-app-demo
# 初始化 package.json 文件
npm init -y
# 安装 nuxt
npm innstall nuxt

在package.json文件的scripts中新增:

"scripts": {"dev": "nuxt"},

上面的配置使得我们可以通过运行 npm run dev 来运行 nuxt。
(2)创建页面并启动项目
创建pages目录: mkdir pages
创建我们的第一个页面 pages/index.vue:

<template>
	<h1>Hello world!</h1>
</template>

然后启动项目:npm run dev
现在我们的应用运行在http://localhost:3000上运行。

注意:Nuxt.js 会监听pages目录中的文件更改,因此在添加新页面时无需重新启动应用程序。
(3)Nuxt 中的基础路由
Nuxt.js 会依据pages目录中的所有*.vue文件生成应用的路由配置。
假设pages的目录结构如下:
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'    
		}  
	]
}

3、案例代码分支说明

git init
.gitignore: node_modules、.nuxt
git status
git add .
git commit -m ‘初始化Nuxt.js项目’

git branch 02-router
git branch
git checkout 02-router

4、路由-基本路由

Nuxt.js 依据pages目录结构自动生成vue-router(https://github.com/vuejs/vue-router)模块的路由配置。
假设pages的目录结构如下:
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'    
		}  
	]
}

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

拿参数$route.params.id
你会发现名称为users-id的路由路径带有:id?参数,表示该路由是可选的。如果你想将它设置为必选的路由,需要在users/_id目录内创建一个index.vue文件。

7、路由-嵌套路由

vue Router嵌套路由

你可以通过 vue-router 的子路由创建 Nuxt.js 应用的嵌套路由

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

Warning:别忘了在父组件(.vue文件) 内增加用于显示子视图内容。

假设文件结构如:
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'       
				 }      
			]    
		}  
	]
}

8、路由-路由配置

参考文档: https://zh-nuxtjs.org/api/configuration-router
nuxt.config.js :Nuxt.js 配置文件
base 配置基础路径
extendRoutes 自定义路由

module.exports = {
	router:{
		base:'/abc',
		// routes 路由配置表
		// resolve 解析路由组件路径
		extendRoutes (routes, resolve){
			routes.push({
				path: '/hello', // 路径也指向about.vue
				name: 'hello',
				component: resolve(__dirname, 'pages/about.vue')
			})
		}
	}
}

访问:http://localhost:3000/abc/

9、视图 -模板

nuxtjs国内镜像下载_vue.js


https://zh-nuxtjs.org/guide/views#布局 模板

<!--  app.html -->
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
  <head {{ HEAD_ATTRS }}>
    {{ HEAD }}
  </head>
  <body {{ BODY_ATTRS }}>
  	<!-- 渲染的内容最终会注入到这里 -->
    {{ APP }}
  </body>
</html>

10、视图 - 布局

默认的是 layouts/default.vue 一旦有了 就所有页面都会有
没有的话,那就没有

<template>
	<div>
		<h1>layouts/default.vue 组件</h1>
		<!-- 页面出口 类似于子路由出口-->
		<nuxt />
	</div>
</template>
<script>
export default {
	name: 'HomePage',
	// layout: 'default' // 默认
	layout: 'foo' // layouts/foo.vue
}
</script>

模板布局
(1)默认布局
(2)自定义布局
(3)错误页面
页面
HTML 页面头部
(1)默认 Meta 标签
(2)个性化特定页面的 Meta 标签

11、异步数据 - asyncData

如何在服务端渲染动态页面

  • 它会将asyncData返回的数据融合组件data方法返回数据一并给组件
  • 调用时机:服务端渲染期间和客户端路由更新之前
  • 注意事项
  • 只能在页面组件中使用,(components中不能使用)
  • 没有this,因为它是在组件初始化之前被调用的
// pages/index.vue
<template>
  <div>
    <h1>{{ title }}</h1>
    <nuxt-link to="/about">About</nuxt-link>
    <br>
    <foo :posts="posts" />
  </div>
</template>

<script>
import axios from 'axios'
import Foo from '@/components/Foo'

export default {
  name: 'HomePage',
  components: {
    Foo
  },

  // 当你想要动态页面内容有利于 SEO 或者是提升首屏渲染速度的时候,就在 asyncData 中发请求拿数据 获取服务端渲染异步数据
  async asyncData () {
    console.log('asyncData')
    console.log(this) // undefined  没有this
    const res = await axios({
      method: 'GET',
      url: 'http://localhost:3000/data.json' // 不补全会默认走到80
    })
    return res.data
  },

  // 如果是非异步数据或者普通数据,则正常的初始化到 data 中即可
  data () {
    return {
      foo: 'bar'
    }
  }
}
</script>

<style>

</style>
// components/Foo.vue
<template>
  <div>
    <h1>FooPage</h1>
    <ul>
      <li
        v-for="item in posts"
        :key="item.id"
      >
        <nuxt-link :to="'/article/' + item.id">{{ item.title }}</nuxt-link>
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'FooPage',
  props: ['posts'],
  // async asyncData () {
  //   console.log('foo asyncData')
  //   return {
  //     foo: 'bar'
  //   }
  // }
}
</script>

<style>

</style>

12、异步数据 - 上下文对象

 nuxtjs国内镜像下载_服务端_02

// pages/article/_id.vue
<template>
  <div>
    <h1>{{ article.title }}</h1>
    <div>{{ article.body }}</div>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'ArticlePage',
  async asyncData (context) {
    console.log(context)
    const { data } = await axios({
      method: 'GET',
      url: 'http://localhost:3000/data.json'
    })
    const id = Number.parseInt(context.params.id)
    return {
      article: data.posts.find(item => item.id === id)
    }
  }
}
</script>

<style>

</style>

nuxtjs国内镜像下载_Vue_03