移动互联网的兴起促进了web前后端分离开发模式的发展,服务端只专注业务,前端只专注用户体验,前端大量运
用的前端渲染技术,比如流行的vue.js、react框架都实现了功能强大的前端渲染。
但是,对于有SEO需求的网页如果使用前端渲染技术去开发就不利于SEO了,有没有一种即使用vue.js、react的前
端技术也实现服务端渲染的技术呢?其实,对于服务端渲染的需求,vue.js、react这样流行的前端框架提供了服务
端渲染的解决方案。
https://zh.nuxtjs.org/guide/
下图展示了从客户端请求到Nuxt.js进行服务端渲染的整体的工作流程:
1、用户打开浏览器,输入网址请求到Node.js
2、部署在Node.js的应用Nuxt.js接收浏览器请求,并请求服务端获取数据
3、Nuxt.js获取到数据后进行服务端渲染
4、Nuxt.js将html网页响应给浏览器
nuxt.js有标准的目录结构,官方提供了模板工程,可以模板工程快速创建nuxt项目。
模板工程地址:https://github.com/nuxt-community/starter-template/archive/master.zip
‐ 资源目录
资源目录 assets 用于组织未编译的静态资源如 LESS、SASS 或 JavaScript。
‐ 组件目录
组件目录 components 用于组织应用的 Vue.js 组件。Nuxt.js 不会扩展增强该目录下 Vue.js 组件,即这些组件不
会像页面组件那样有 asyncData 方法的特性。
‐ 布局目录
布局目录 layouts 用于组织应用的布局组件。
该目录名为Nuxt.js保留的,不可更改。
‐ 中间件目录
middleware 目录用于存放应用的中间件。
‐ 页面目录
页面目录 pages 用于组织应用的路由及视图。Nuxt.js 框架读取该目录下所有的 .vue 文件并自动生成对应的路由配
置。
该目录名为Nuxt.js保留的,不可更改。
‐ 插件目录
插件目录 plugins 用于组织那些需要在 根vue.js应用 实例化之前需要运行的 Javascript 插件。
‐ 静态文件目录
静态文件目录 static 用于存放应用的静态文件,此类文件不会被 Nuxt.js 调用 Webpack 进行构建编译处理。 服务
器启动的时候,该目录下的文件会映射至应用的根路径 / 下。
举个例子: /static/logo.png 映射至 /logo.png
该目录名为Nuxt.js保留的,不可更改。
‐ Store 目录
store 目录用于组织应用的 Vuex 状态树 文件。 Nuxt.js 框架集成了 Vuex 状态树 的相关功能配置,在 store 目
录下创建一个 index.js 文件可激活这些配置。
该目录名为Nuxt.js保留的,不可更改。
‐ nuxt.config.js 文件
nuxt.config.js 文件用于组织Nuxt.js 应用的个性化配置,以便覆盖默认配置。
该文件名为Nuxt.js保留的,不可更改。
‐ package.json 文件
package.json 文件用于描述应用的依赖关系和对外暴露的脚本接口。
该文件名为Nuxt.js保留的,不可更改。
nuxt.js 提供了目录的别名,方便在程序中引用:
页面布局就是页面内容的整体结构,通过在layouts目录下添加布局文件来实现。在layouts 根目录下的所有文件都
属于个性化布局文件,可以在页面组件中利用 layout 属性来引用。
例:
定义:layouts/test.vue布局文件,如下:
注意:布局文件中一定要加 组件用于显示页面内容。
<template>
<div>
<div>这里是头div>
<nuxt/>
<div>这里是尾div>
div>
template>
<script>
export default {
}
script>
<style>
style>
在pages目录创建user目录,并创建index.vue页面
在 pages/user/index.vue 页面里, 可以指定页面组件使用 test 布局,代码如下:
<template>
<div>
测试页面
div>
template>
<script>
export default{
layout:'test'
}
script>
<style>
style>
测试,请求:http://localhost:10000/user,如果如下:
基础路由
Nuxt.js 依据 pages 目录结构自动生成 vue-router 模块的路由配置。
index.vue 代码如下:
<template>
<div>
用户管理首页
div>
template>
<script>
export default{
layout:"test"
}
script>
<style>
style>
one.vue代码如下:
<template>
<div>
one页面
div>
template>
<script>
export default{
layout:"test"
}
script>
<style>
style>
分别访问如下链接进行测试:
http://localhost:10000/user
http://localhost:10000/user/one
嵌套路由
你可以通过 vue-router 的子路由创建 Nuxt.js 应用的嵌套路由。
创建内嵌子路由,你需要添加一个 Vue 文件,同时添加一个与该文件同名的目录用来存放子视图组件。
别忘了在父级 Vue 文件内增加
将user.vue文件创建到与user目录的父目录下,即和user目录保持平级。
<template>
<div>
用户管理导航,<nuxt‐link :to="'/user/101'">修改nuxt‐link>
<nuxt‐child/>
div>
template>
<script>
export default{
layout:"test"
}
script>
<style>
style>
_id.vue页面实现了向页面传入id参数,页面内容如下:
<template>
<div>
修改用户信息{{id}}
div>
template>
<script>
export default{
layout:"test",
data(){
return {
id:''
}
},
mounted(){
this.id = this.$route.params.id;
console.log(this.id)
}
}
script>
<style>
style>
测试:http://localhost:10000/user
asyncData 方法
Nuxt.js 扩展了 Vue.js,增加了一个叫 asyncData 的方法, asyncData 方法会在组件(限于页面组件)每次加载
之前被调用。它可以在服务端或路由更新之前被调用。 在这个方法被调用的时候,第一个参数被设定为当前页面的
上下文对象,你可以利用 asyncData 方法来获取数据,Nuxt.js 会将 asyncData 返回的数据融合组件 data 方法
返回的数据一并返回给当前组件。
注意:由于 asyncData 方法是在组件 初始化 前被调用的,所以在方法内是没有办法通过 this 来引用组件的实例
对象。
<template>
<div>
修改用户信息{{id}},名称:{{name}}
div>
template>
<script>
export default{
layout:'test',
//根据id查询用户信息
asyncData(){
console.log("async方法")
return {
name:'程序员'
}
},
data(){
return {
id:''
}
},
mounted(){
this.id = this.$route.params.id;
}
}
script>
<style>
style>
async /await方法
使用async 和 await配合promise也可以实现同步调用,nuxt.js中使用async/await实现同步调用效果。
先测试异步调用,增加a、b两个方法,并在mounted中调用。
methods:{
a(){
return new Promise(function(resolve,reject){
setTimeout(function () {
resolve(1)
},2000)
})
},
b(){
return new Promise(function(resolve,reject){
setTimeout(function () {
resolve(2)
},1000)
})
}
},
mounted(){
this.a().then(res=>{
alert(res)
console.log(res)
})
this.b().then(res=>{
alert(res)
console.log(res)
})
}
使用async/await完成同步调用
async asyncData({ store, route }) {
console.log("async方法")
var a = await new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("1")
resolve(1)
},2000)
});
var a = await new Promise(function (resolve, reject) {
setTimeout(function () {
console.log("2")
resolve(2)
},1000)
});
return {
name:'程序员'
}
},