Vue开始使用NUXT框架开发

前言

Nuxt.js 为 客户端/服务端 这种典型的应用架构模式提供了许多有用的特性,例如服务端渲染、SEO、中间件支持、布局支持等。

所以用Nuxt的项目的环境必须有Node.js

官方文档

后话 目前已经不用Nuxt了 服务端和客户端渲染是有很多优点,但同时也带来了些麻烦,比如生命周期不但涉及服务端也涉及客户端,那些对象在哪个生命周期能用,以及SEO也可以通过其他手段实现,并且部署必须有Node.js环境,如果后端不是Node.js,就不建议使用了

生命周期

20181220154528705898598.png

生命周期流程图

  • 红框内的是Nuxt的生命周期(运行在服务端)

  • 黄框内同时运行在服务端&&客户端上

  • 绿框内则运行在客户端

Vue的生命周期全都跑在客户端(浏览器),而Nuxt的生命周期有些在服务端(Node)客户端,甚至两边都在

所以,红框、黄框内的周期都不存在Window对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
export default {
asyncData() {
console.log(window) // 服务端报错
},
fetch() {
console.log(window) // 服务端报错
},
created () {
console.log(window) // undefined
},
mounted () {
console.log(window) // Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}
}
}
</script>

文件(static/assets)

  • 静态文件目录

静态文件目录 static 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下。

举个例子: /static/robots.txt 映射至 /robots.txt

该目录名为Nuxt.js保留,不可更改。

  • 资源目录

资源目录 assets 用于组织未编译的静态资源如 LESSSASSJavaScript

对于JS来说,需要构建编译的放在assets目录中 不需要的放在static

视图(Document/Layout/Page)

与视图有关的有模版(Document),布局(Layout),页面(Page)

模版只能有一个,可以自定义也可以用默认的

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

默认模板为:

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>

举个例子,你可以修改模板添加 IE 的条件表达式:

1
2
3
4
5
6
7
8
9
10
<!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>

layouts 目录下的所有文件都属于个性化布局文件,可以在页面组件中利用 layout 属性来引用。

请确保在布局文件里面增加 组件用于显示页面非布局内容。

举个例子 layouts/blog.vue:

1
2
3
4
5
6
<template>
<div>
<div>这里是博客导航</div>
<nuxt/>
</div>
</template>

pages/posts.vue 里, 可以指定页面组件使用 blog 布局。

1
2
3
4
5
<script>
export default {
layout: 'blog'
}
</script>

Meta标签

全局配置

nuxt.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
module.exports = {
head: {
title: pkg.name,
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: pkg.description }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
]
}
}

局部配置

页面内

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
export default {
head () {
return {
title:"首页",
meta: [
{
name: '资讯',
content: '资讯描述'
},
],
script: [
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' }
],
link: [
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css?family=Roboto' }
]
}
}
}
</script>

引用JS插件的三种方式

比如我们页面要用到jquery

插件形式引用

首先在项目内运行

1
npm install --save jquery

plugins目录下创建jq.js文件

1
2
let $ = require('jquery')
window.$ = $

nuxt.config.js中配置

1
2
3
4
5
6
7
8
module.exports = {
plugins: [
{
src: '~plugins/jq.js',
ssr: false
}
]
}

全局头部引用

1
2
3
4
5
6
7
module.exports = {
head: {
script: [
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' }
]
}
}

页面头部引用

1
2
3
4
5
6
7
8
9
<script>
export default {
head: {
script: [
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' }
]
}
}
</script>

数据(fetch/asyncData/validate)

fetch、asyncData、validate使用范围

只能在页面组件使用,也就是pages目录下的组件,而不是components和layout目录下的组件,要有所区分

asyncData 多请求

由于asyncData方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例对象。

Nuxt.js框架中asyncData方法只能在pages中的.vue文件页面中使用。

如果要一次发送多个请求可进入如下操作:

1
2
3
4
5
6
7
8
9
10
11
12
async asyncData ({ params, error }) {
let [request1Data, request2Data, request3Data] = await Promise.all([
axios.get('/api/home/request1'),
axios.get('/api/home/requset2'),
axios.get('/api/home/request3')
])
return {
data1: request1Data.data,
data2: request2Data.data,
data3: request3Data.data
}
}