Vue.js 是目前最火热的前端框架之一,而 Nuxt.js 是针对 Vue.js 推出的服务端渲染框架,经过高度定制化的配置以及简洁的 API,开发者能够快速进行服务端渲染项目的开发,本文将对 Nuxt.js 框架作一个简要介绍。css
服务端渲染(Server Side Render)并非一个新的概念,在单页应用(SPA)尚未流行起来的时候,页面就是经过服务端渲染好,并传递给浏览器的。当用户须要访问新的页面时,须要再次请求服务器,返回新的页面。前端
为了优化体验,开发者们开始选择采用 JavaScript 在前端完成渲染过程,用先后端分离的手段,使后端更专一于数据,而前端注重于处理展现,经过设计良好的 API 以及 Ajax 技术完成先后端的交互,jQuery、React.js、Vue.js、Angular.js 等框架应运而生。vue
这些框架给开发者带来了巨大的便利,可是对于一些论坛、资讯网站、或是企业的官方网站来讲,他们对搜索引擎优化(SEO)有强烈的要求,而前端渲染技术是没法知足他们的需求的。若是没法经过搜索引擎的搜索输出自身的内容,那么网站的价值就会大大受影响,要解决这类问题,仍是要靠服务端渲染。jquery
本文会介绍 Vue.js 的服务端渲染解决方案 Nuxt.js。Vue.js 推出后,其数据驱动和组件化思想,以及简洁易上手的特性给开发者带来了巨大的便利,Vue.js 官方提供的 vue-server-renderer
能够用来进行服务端渲染的工做,可是须要增长额外的工做量,开发体验仍有待提升,而 Nuxt.js 推出后,这个问题被很好的解决了。ios
Nuxt.js 是一个基于 Vue.js 的通用应用框架,Nuxt.js 预设了利用 Vue.js 开发服务端渲染的应用所须要的各类配置,而且能够一键生成静态站点。同时,Nuxt.js 的热加载机制可使开发者很是便捷的进行网站的开发。vue-router
Nuxt.js 于 2016 年 10 月 25 号发布,上线还不足一年,可是已经受到了普遍的好评,最新的稳定版本是 0.10.7,目前仍在进行 1.0 版本的内测,Nuxt.js 社区也在逐步完善中,官网已经支持了中文文档。vue-cli
Vue.js 的 vue-cli
工具能够很方便的让咱们使用现成的模板初始化 Vue.js 项目,而 Nuxt.js 团队已经为咱们提供了初始化 Nuxt.js 项目的模板,安装 vue-cli
后,只需在命令行中输入npm
vue init nuxt/starter <projectName>复制代码
便可完成项目的建立工做,而后进入项目目录中执行如下命令:bootstrap
npm install
npm run dev复制代码
Nuxt.js 会使用 3000
端口运行服务,在浏览器中输入 http://localhost:3000
就能够看到一个带有 Nuxt.js 的 logo 的原始的页面了。axios
完成了一个简单的 Hello World 项目后,咱们来进一步研究 Nuxt.js。进入 Nuxt.js 项目后,项目目录以下:
下面简要介绍一下各个目录的做用:
.nuxt/
:用于存放 Nuxt.js 的核心库文件。例如,你能够在这个目录下找到 server.js
文件,描述了 Nuxt.js 进行服务端渲染的逻辑(参见下一段 “Nuxt.js 的渲染流程”),router.js
文件包含一张自动生成的路由表。
assets/
:用于存放静态资源,该目录下的资源使用 Webpack 构建。
components/
:存放项目中的各类组件。注意,只有在这个目录下的文件才能被称为组件。
layouts/
:建立自定义的页面布局,能够在这个目录下建立全局页面的统一布局,或是错误页布局。若是须要在布局中渲染 pages
目录中的路由页面,须要在布局文件中加上 <nuxt />
标签。
middleware/
:放置自定义的中间件,会在加载组件以前调用。
pages/
:在这个目录下,Nuxt.js 会根据目录的结构生成 vue-router
路由,详见下文。
plugins/
:能够在这个目录中放置自定义插件,在根 Vue
对象实例化以前运行。例如,能够将项目中的埋点逻辑封装成一个插件,放置在这个目录中,并在 nuxt.config.js
中加载。
static/
:不使用 Webpack 构建的静态资源,会映射到根路径下,如 robots.txt
store/
:存放 Vuex 状态树。
nuxt.config.js
:Nuxt.js 的配置文件,详见下文。
Nuxt.js 经过一系列构建于 Vue.js 之上的方法进行服务端渲染,具体流程以下:
调用 nuxtServerInit
方法
当请求打入时,最早调用的便是 nuxtServerInit
方法,能够经过这个方法预先将服务器的数据保存,如已登陆的用户信息等。另外,这个方法中也能够执行异步操做,并等待数据解析后返回。
Middleware
层
通过第一步后,请求会进入 Middleware
层,在该层中有三步操做:
nuxt.config.js
中全局 middleware
字段的配置,并调用相应的中间件方法layout
layout
和 page
的中间件方法调用 validate
方法
在这一步能够对请求参数进行校验,或是对第一步中服务器下发的数据进行校验,若是校验失败,将抛出 404 页面。
调用 fetch
及 asyncData
方法
这两个方法都会在组件加载以前被调用,它们的职责各有不一样,asyncData
用来异步的进行组件数据的初始化工做,而 fetch
方法偏重于异步获取数据后修改 Vuex 中的状态。
咱们在 Nuxt.js 的源码 util.js
中能够看到如下方法:
export function applyAsyncData (Component, asyncData = {}) {
const ComponentData = Component.options.data || noopData
Component.options.data = function () {
const data = ComponentData.call(this)
return { ...data, ...asyncData }
}
if (Component._Ctor && Component._Ctor.options) {
Component._Ctor.options.data = Component.options.data
}
}复制代码
这个方法会在 asyncData
方法调用完毕后进行调用,能够看到,组件从 asyncData
方法中获取的数据会和组件原生的 data
方法获取的数据作一次合并,最终仍然会在 data
方法中返回,因此得出,asyncData
方法实际上是原生 data
方法的扩展。
通过以上四步后,接下来就是渲染组件的工做了,整个过程能够用下图表示:
(图片来源:Nuxt.js 官网)
如上文所述,在 .nuxt
目录下,你能够找到 server.js
文件,这个文件封装了 Nuxt.js 在服务端渲染的逻辑,包括一个完整的 Promise
对象的链式调用,从而完成上面描述的整个服务端渲染的步骤。
nuxt.config.js
是 Nuxt.js 的配置文件,能够经过针对一系列参数的设置来完成 Nuxt.js 项目的配置,能够在 Nuxt.js 官网 找到针对这个文件的说明,下面举例一些经常使用的配置:
head: 能够在这个配置项中配置全局的 head
,如定义网站的标题、meta
,引入第三方的 CSS、JavaScript 文件等:
head: {
title: '百姓店铺',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ name: 'applicable-device', content: 'pc,mobile' },
],
link: [
{ rel: 'stylesheet', type: 'text/css', href: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'}
],
script: [
{src: 'https://code.jquery.com/jquery-3.1.1.min.js'},
{src: 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js'}
]
},复制代码
build: 这个配置项用来配置 Nuxt.js 项目的构建规则,即 Webpack 的构建配置,如经过 vendor 字段引入第三方模块,经过 plugin 字段配置 Webpack 插件,经过 loaders 字段自定义 Webpack 加载器等。一般咱们会在 build 的 vendor 字段中引入 axios
模块,从而在项目中进行 HTTP 请求(axios
也是 Vue.js 官方推荐的 HTTP 请求框架)。
build: {
vendor: ['core-js', 'axios'],
loaders: [
{
test: /\.(scss|sass)$/,
use: [{
loader: "style-loader"
}, {
loader: "css-loader"
}, {
loader: "sass-loader"
}]
},
{
test: /\.(png|jpe?g|gif|svg)$/,
loader: 'url-loader',
query: {
limit: 1000,
name: 'img/[name].[hash:7].[ext]'
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 1000,
name: 'fonts/[name].[hash:7].[ext]'
}
}
]
}复制代码
css: 在这个配置项中,引入全局的 CSS 文件,以后每一个页面都会被引入。
router: 能够在此配置路由的基本规则,以及进行中间件的配置。例如,你能够建立一个用来获取 User-Agent
的中间件,并在此加载。
loading: Nuxt.js 提供了一套页面内加载进度指示组件,能够在此配置颜色,禁用,或是配置自定义的加载组件。
env: 能够在此配置用来在服务端和客户端共享的全局变量。
Nuxt.js 在 vue-router
之上定义了一套自动化的生成规则,即依据 pages 的目录结构生成。例如,咱们有如下目录结构:
这个目录下含有一个基础路由(无参数)以及两个动态路由(带参数),Nuxt.js 会生成以下的路由配置表(能够在 .nuxt
目录下的 router.js
文件中找到):
routes: [
{
path: "/",
component: _abe13a78,
name: "index"
},
{
path: "/article/:id?",
component: _48f202f2,
name: "article-id"
},
{
path: "/:page",
component: _5ccbb43a,
name: "page"
}
]复制代码
对于 article-id
这个路由,路径中带有 :id?
参数,代表这是一个可选的路由,若是要将其设为必选,则必须在 article
的目录下添加 index.vue
文件。
再看下面一个例子:
因为有同名文件和文件夹的存在,Nuxt.js 会为咱们生成嵌套路由,生成的路由结构以下,在使用时,须要增长 <nuxt-child />
标签来显示子视图的内容。
routes: [
{
path: "/article",
component: _f930b330,
children: [
{
path: "",
component: _1430822a,
name: "article"
},
{
path: ":id",
component: _339e8013,
name: "article-id"
}
]
}
]复制代码
此外,Nuxt.js 还能够设置动态嵌套路由,具体可参见 Nuxt.js 的官方文档。
Nuxt.js 尽管是一个很是年轻的框架,目前也有不少待改进的问题,但它的出现为 Vue.js 开发者搭建服务端渲染项目提供了巨大的便利,期待 Nuxt.js 1.0 版本发布后,能给咱们带来更多实用的新功能。
做者:李韧
简介:百姓网商业化运营中心技术团队成员。本文仅为做者我的观点,不表明百姓网立场。
本文在 “百姓网技术团队” 微信公众号首发,扫码当即订阅: