【学习】服务端渲染框架Nuxt入门
对着官方文档一顿敲= = 看官方文档就好,很简单,相比Vue和React那坑爹的服务端渲染配置,Nuxt简直是良心多了,配置灵活,最重要的是简单!!!于是近期会把 我的个人站首页用nuxt重(折腾)构一番,敬请期待~
Nuxt
Nuxt.js(后文Nuxt)是基于Vue.js的通用应用框架
通过对客户端/服务端基础架构的抽象组织,Nuxt主要关注的是应用的UI渲染。其预设了利用Vue开发服务端渲染的应用所需要的各种配置。
作为框架,Nuxt.js 为 客户端/服务端 这种典型的应用架构模式提供了许多有用的特性,例如异步数据加载、中间件支持、布局支持等。
基本介绍
如何运作
vue2+ vue-router vuex vue-meta
以及webpack、vue-loader、babel-loader来处理代码的自动化构建工作
特性
- 基于Vue
- 自动代码分层
- 服务端渲染
- 强大的路由功能,支持异步数据
- 静态服务文件
- ES6+语法支持
- 打包和压缩JS/CSS
- HTML头部标签管理
- 本地开发支持热加载
- 集成ESLint
- 支持样式预处理
下图阐述了 Nuxt.js 应用一个完整的服务器请求到渲染(或用户通过 <nuxt-link>
切换路由渲染页面)的流程:
请求到来 -> nuxt server拦截处理(事件派发store action) -> middleware处理中间件 (先配置,后布局,再页面) -> 验证 -> 获取异步数据 -> render渲染(通过Navigate作路由跳转)
服务端渲染
使用nuxt作UI渲染框架。当运行nuxt
命令时会启动一个支持热加载
和服务端渲染
(基于Vue的vue-server-renderer模块)的开发服务器。
静态化
nuxt generate
通过CDN缓存静态页面,进行全球CDN节点布局。相对传统的动态网站,静态化分散了对服务器的请求,降低服务器压力。
简而言之,页面静态文件CDN,数据通过API,前后端分离.
demo
安装
vue init nuxt-community/starter-template nuxt-demo
要注意,服务端渲染
是前台服务端用相同组件,一份代码,我们跑的其实是静态文件,所以需要打包出来一份bundle
npm run build
npm run dev
现在浏览器打开 localhost:3000 就可以访问nuxt-demo了
目录结构
assets 组织静态资源 css js等
components 放公共组件。注:nuxt不会扩展该目录下的组件,所以不会有asyncData特性
layouts 用于组织布局,除配置外这个优先级很高
middleware 存放中间件
pages 组织页面及路由,在layouts后读取,配置这个就不用写routes了. 后面介绍很爽
plugins 插件,用于组织需要在根vue.js实例化之前运行的JS插件
static 静态文件目录,不会被nuxt调用构建。服务启动,该目录下文件会被映射到根路径下
store Vuex状态文件
nuxt.config.js nuxt配置,优先级最高,用于覆盖默认配置
更多请参考官方文档 https://zh.nuxtjs.org ~
路由
Nuxt根据pages
目录结构自动生成vue-router模块路由配置,就问你叼不叼~
在pages下新建一个user文件夹,新建index.vue one.vue
访问 localhost:3000/user localhost:3000/user/one 就能显示了,简直不要太爽
动态路由
以前path里配置 /:id
这样的,在pages/user 里新建 _id.vue即可
路由参数校验
pages/users/_id.vue
1 | export default { |
嵌套路由
pages/
–| users/
—–| _id.vue
—–| index.vue
–| users.vue
过渡动效
参考文档 - - 我没跑成功,回头再看看
中间件
允许定义一个自定义函数运行在一个页面或一组页面渲染之前。放在middleware目录下,一个中间件接收context
作为第一个参数:
1 | export default function(context) { |
中间件执行顺序:
- nuxt.config.js
- 匹配布局
- 匹配页面
中间件可异步执行,只需返回一个Promise
或使用第二个callback作为第一个参数:
middleware/stats.js
1 | import axios from 'axios' |
然后在 上面3个任意地方使用中间件:
1 | module.exports = { |
stats中间件将在每个路由改变时被调用。
视图
默认页面
layouts/default.vue
错误页面
layouts/error.vue
个性化布局
在layouts里添加一个dark.vue文件,然后在pages里的组件写.
1 | export default { |
页面
页面的一些api
属性名 | 描述 |
---|---|
asyncData | 最重要的一个键, 支持 异步数据处理,另外该方法的第一个参数为当前页面组件的 上下文对象 |
fetch | 与 asyncData 方法类似,用于在渲染页面之前获取数据填充应用的状态树(store)。不同的是 fetch 方法不会设置组件的数据。详情请参考 关于fetch方法的文档 |
head | 配置当前页面的 Meta 标签, 详情参考 页面头部配置API |
layout | 指定当前页面使用的布局(layouts 根目录下的布局文件)。详情请参考 关于 布局 的文档 |
transition | 指定当前页面使用的布局(layouts 根目录下的布局文件)。详情请参考 关于 布局 的文档 |
scrollToTop | 布尔值,默认: false。 用于判定渲染页面前是否需要将当前页面滚动至顶部。这个配置用于 嵌套路由的应用场景 |
middleware | 指定页面的中间件,中间件会在页面渲染之前被调用, 请参考 路由中间件 |
HTML头部
nuxt使用vue-meta
更新应用头部标签和html属性
1 | { |
异步数据
Nuxt扩展了Vue增加一个asyncData方法,使得我们可以在设置组件数据前异步获取处理数据
asyncData
该方法会在组件(限于页面组件)每次加载前被调用。它可以在服务端或路由更新之前被调用。在该方法被调用时,第一个参数被设定为当前页面的上下文对象
,可利用asyncData
方法来获取数据,Nuxt会将asyncData返回的数据融合组件data
方法返回的数据一并返回给当前组件。
由于asyncData方法是在组件初始化前被调用的,所以在方法内是无法通过this来引用组件实例对象的。
使用:
- 返回Promise
1 | asyncData({params, error}) { |
- 使用async/await
1 | asyncData({params, error}) { |
资源文件
默认Nuxt使用vue-loader、file-loader及url-loader来处理文件的加载和引用。对于不需要通过webpack处理的静态资源文件,可以放置在static目录中
webpack构建
默认情况下, vue-loader自动使用 css-loader 和Vue模板编译器来编译处理vue文件中的样式和模板。在此编译过程中,所有的资源URL例如 <img src="...">
、 background: url(...)
和 CSS中的 @import
均会被解析成模块通过 require 引用。
静态文件
如果你的静态资源文件需要 Webpack 做构建编译处理,可以放到 assets 目录,否则可以放到 static 目录中去。
Nuxt 服务器启动的时候,该目录下的文件会映射至应用的根路径 / 下,像 robots.txt 或 sitemap.xml 这种类型的文件就很适合放到 static 目录中。
你可以在代码中使用根路径 / 结合资源相对路径来引用静态资源:
1 | <!-- 引用 static 目录下的图片 --> |
插件
使用第三方模块
在页面内直接 import。但是,如果在另一页面也import相同第三方模块,在打包时该模块会被重复打包,而实际上我们只需要打包一次。该问题可以通过在nuxt.config.js
里配置build.vendor
来解决:
1 | module.exports = { |
使用Vue插件
plugins里增加相应插件的js文件,如xxx.js
1 | module.exports = { |
使用Vuex
Nuxt已内置了Vuex,所以不需额外安装和use了。
模块方式
状态树还可以拆分成为模块,store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块
使用状态树模块化的方式,store/index.js 不需要返回 Vuex.Store 实例,而应该直接将 state、mutations 和 actions 暴露出来:
fetch方法
fetch 方法会在渲染页面前被调用,作用是填充状态树 (store) 数据,与 asyncData 方法类似,不同的是它不会设置组件的数据。
nuxtServerInit方法
如果在状态树中指定了nuxtServerInit
方法,Nuxt调用它时会将页面的上下文对象作为第2个参数传给它(仅在服务端调用时)。当我们想将服务端数据传到客户端时,就可用此方法。
如,服务端会话状态树可以通过 req.session.user
来访问当前登录用户。将该登录用户信息传给客户端的状态树,只需要更新 store/index.js
,如下:
1 | actions: { |
如果你使用状态树模块化的模式,只有主模块(即 store/index.js)适用设置该方法(其他模块设置了也不会被调用)。nuxtServerInit 方法接收的上下文对象和 fetch 的一样,但不包括 context.redirect() 和 context.error()。
命令
命令 | 描述 |
---|---|
nuxt | 启动一个热加载的Web服务器(开发模式) localhost:3000 |
nuxt build | 利用webpack编译应用,压缩JS和CSS资源(发布用) |
nuxt start | 以生成模式启动一个Web服务器 (nuxt build 会先被执行) |
nuxt generate | 编译应用,并依据路由配置生成对应的HTML文件 (用于静态站点的部署) |
大致就这样了,试着自己折腾一下吧。对了,正好可以把个人网站首页用nuxt重构静态发布~~
生命不息,折腾不止!~