Fork me on GitHub

Nuxt.js及Vue-SSR学习笔记

Nuxt.js基础

  • Vue2
  • Vue Router
  • Vuex
  • Vue Server Renderer
  • vue-meta

首先还是官方地址给上。

安装:

1
2
3
4
// 先安装一下vue-cli工具
yarn global add @vue/cli-init
// 初始化模板
vue init nuxt-community/koa-template

还源的工具可以使用nrm,类似于版本控制的npm

1
nrm ls

nuxt.js是非常适合做vuessr渲染的,他可以让ssr变得非常非常简单。

我们直接利用刚才那个命令来生成一个nuxt.js模板。

1
vue init nuxt-community/koa-template nuxt-start

不过这里可能会遇见一个问题。具体可以参考,项目的README.md文档

这东西的设计其实和umi很类似(可能umi是借鉴了这边吧。。)有一点就是pages目录下面的文件即为路由。我们创建一个xxx.vue,然后去localhost:3000/xxx,就可以直接访问到对应的页面了。

那个layouts就是一个公共的模板。里面有个公用的footer。里面会有个default.vue就是默认的模板。

里面会有这样的模板代码:

1
2
3
4
5
6
<template>
<div>
<nuxt/>
<my-footer/>
</div>
</template>

我们pages里面的代码都会被生成出来放到<nuxt /> 里面去,而模板文件则会被放在例如<my-footer />那里去。

如果我们想要自定义一个模板,直接在layouts下面新建一个search.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div class="layout-search">
<h1>search layout header</h1>
<nuxt />
<footer>search layout footer</footer>
</div>
</template>
<script>
export default {
}
</script>
<style>
.layout-search {
color: red;
}
</style>

然后如果要使用这个模板,直接在pages目录下面的search.vue里面引入一下就可了。

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<div class="page">
Page is Search
</div>
</template>
<script>
export default {
layout: 'search'
}
</script>
<style>
</style>

这样去访问search这个路由的时候相对应的layouts就会显示上去。

其中里面全局的css设定可以在nuxt.config.js里面可以看见,assets/cssmain.css被设定成为了全局的css

接口相关

koa2相关的目录就是server下面的index.js,里面的配置其实也不用改什么了。

我们去server目录下面新建一个interface目录,然后里面放一个city.js,其代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
import Router from 'koa-router'
const router = new Router({
prefix: '/city'
})
router.get('/list', async (ctx) => {
ctx.body = {
list: ['北京', '天津']
}
})
export default router

然后去index.js里面使用一下这个路由:

1
2
3
import cityInterface from './interface/city'
app.use(cityInterface.routes()).use(cityInterface.allowedMethods())

然后我们可以在search.vue里面去搞一发:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<template>
<div class="page">
Page is Search
<ul>
<li v-for="(item,index) in list" :key="index">{{item}}</li>
</ul>
</div>
</template>
<script>
import axios from 'axios'
export default {
layout: 'search',
data () {
return {
list: []
}
},
// 用这个类似于componentDidmout()的函数去进行一个数据请求
async mounted () {
let self = this;
let { status, data: { list } } = await axios.get(`/city/list`)
if (status === 200) {
self.list = list
}
}
}
</script>
<style>
</style>

这里我们刷新页面去看,会发现使用vue里面的生命周期函数去请求的话,到了页面里面,渲染的地方会发生短暂的闪烁,同时查看源码的话,是没有任何结果显示出来的。

这里如果我们换成nuxt.js里面专门的api的话,就相当于将数据已经存储在服务器端了,然后再利用ssr去将数据渲染出来,这里就不会出现上面那种在浏览器端去请求数据的情况了。

1
2
3
4
5
6
7
8
async asyncData () {
let { status, data: { list } } = await axios.get(`http://localhost:3000/city/list`)
if (status === 200) {
return {
list
}
}
}

这样去查看源代码的话,就会显示成模板显示成功的样子。

如果我们把asyncData改成fetch的话(他们两个api都可以获得数据),但是如果使用fetch会发现并不会获得到数据,是因为fetch是用来处理和vuex相关的数据,而asyncData则是用来处理和组件相关的数据,所以使用fetch并不会拿到数据。所以这里就要用asyncData(),想在初始状态那里拿到一些数据是可以使用fetch的。

vuex在SSR里面的使用

可以根据nuxt.js里面的文档来查看vuex的使用,同样的也是文件即为配置使用方法。

这样直接创建一个示例就明白了:
根据官方文档的需求,我们直接在根目录下面创建一个store目录,里面用来放vuex相关的文件,我们先建立两个示例文件:

store/modules/city.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const state = () => ({
list: ['a', 'b']
})
const mutations = {
add (state, text) {
state.list.push(text)
}
}
const actions = {
add: ({ commit }, text) => {
commit('add', text)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

store/modules/navbar.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const state = () => ({
app: []
})
const mutations = {
add (state, text) {
state.list.push(text)
}
}
const actions = {
add: ({ commit }, text) => {
commit('add', text)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

然后根目录下面的文件为store/index.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import Vue from 'vue'
import Vuex from 'vuex'
import city from './modules/city'
import navbar from './modules/navbar'
Vue.use(Vuex)
const store = () => new Vuex.Store({
modules: {
city,
navbar
},
// 把实例放在数据里面验证一下
actions: {
}
})
export default store

假如我们想在vue里面直接调用数据的话,这里都不用像vue-cli里面那样去注册啥,直接就可以调用了,假设我们想调用city.js里面的state数据,直接使用$store去调用就可以了。

1
2
3
<ul>
<li v-for="(item,index) in $store.state.city.list" :key="index">{{item}}</li>
</ul>

注意每次修改了vuex的相关配置之后,都要记得重启即可

这里的数据也是和服务端同步的,都会被挂载到dom下面去。

-------------本文结束感谢您的阅读-------------