Nuxt 开发记录

Nuxt.js是一个基于Vue.js的通用应用架构, 它预设了服务端渲染(SSR, Server Side Render)应用所需要的相关配置, 同时也支持生成静态站点.

1_EWDEUt0fqsmRgpYGFOOMew.png

1. 背景 & Nuxt简介

Nuxt 其一目的是为了解决单页面应用的SEO问题, 相比于我们平常的SPA页面. 在搜索引擎中由于无法从网页中被抓取内容信息(SPA页面的信息都是被打包到JS文件中,动态加载到页面中), 从而无法被用户所搜索到.
其二是服务端渲染相比于SPA页面渲染,在网络环境较差或者客户端运行在没有JavaScript的引擎上, 这时基于SSR渲染的页面能更好的展现原有的页面的内容,而单页面应用可能就会有很长的空白时间, 从而影响到用户的体验.

2. Nuxt应用架构

ujs-architecture.jpg
  • 客户端向服务器请求数据
  • 服务器端获取数据从API服务器
  • 服务端返回完整HTML页面给客户端
  • 客户端页面渲染使用SPA
  • 客户端直接请求API服务器

3. 项目创建

为了更加方便快速的创建项目, Nuxt.js 团队提供了一个脚手架工具 create-nuxt-app.确保你已经安装 npx (npx 已经被内置自 NPM 5.2.0)

$ npx create-nuxt-app <project-name>

它会让你进行一些选择:
- 在集成的服务器端框架之间进行选择:
- None(默认服务器)
- Express
- Koa
- Hapi
- Feathers
- Micro
- Adonis
- 选择您喜欢的UI框架:
- None
- Bootstrap
- Vuetify
- Bulma
- Tailwind
- Element UI
- Ant Design Vue
- Buefy
- 选择你想要的Nuxt模式(universal or SPA)
- 选择axios module
- 选择 Eslint
- 选择 Prettier
当运行完成时,它将安装所有依赖项,完成后启动项目:

$ npm run dev

应用现在会运行在 http://localhost:3000

4. 项目开发

4.1 目录结构

WX20181218-115512.png
  • api: api接口
  • assets:静态资源
  • components:组件
  • layouts: 布局目录
  • logs: 日志
  • middleware:中间件
  • pages: 页面目录
  • plugins:插件
  • nuxt.config.js: nuxt 配置文件

4.2 配置

Nuxt.js默认的配置涵盖了大部分的使用情形, 也可以通过修改 nuxt.config.js 来进行自定义配置.

WX20181218-121625@2x.png

  • plugins: 全局引入的插件
  • css: 全局引入的css, scss 等
  • head: 可以设置pages的头部信息, 如titile, meta信息等
  • loading:页面切换的时候加载组件显示的进度条
  • build: 自定义webpack的构建配置
  • env: 配置客户端和服务端共享的环境变量
  • cache:是否允许缓存
  • router:自定义配置vue-router的信息

4.3 路由

WX20181218-151044@2x.png

Nuxt.js 会根据pages的目录结构, 自动生成vue-router模块的路由配置. 如上图, 会生成 /dashboard/h5/:h5 , /dashboard/mws/:mws, ...
可以看出路径根据目录结构自动生成了, 动态路径需要在名字前添加下划线( _ )

4.4 布局

nuxt-views-schema.png

上图是Nuxt.js的布局架构. 最外层依旧是Document, 往里一层是一个layout层,在 Nuxt里面对应目录中的layouts文件夹,默认的pages下的页面都会套用 layouts/default.vue 的布局样式. 其中 <nuxt/> 相当于Vue中的 slot插槽的概念,
pages/**.vue的内容都会被填入<nuxt/>,其他的内容嵌套和平时的Vue单页面应用开发是一样的.

4.5 Vuex

在根目录创建 store 目录,就会默认引用 vuex 模块,除此之外,还进行了以下的操作:1)将 vuex 模块 加到 vendors 构建配置中去;2)设置 Vue 根实例的 store 配置项.
Nuxt.js 支持两种使用 store 的方式:

  • 普通方式:store/index.js 返回一个 Vuex.Store 实例
  • 模块方式:store 目录下的每个 .js 文件会被转换成为状态树指定命名的子模块 (当然,index 是根模块,相当于设置了namespaced: true)

Nuxt.js提供了模块方式的简单写法:使用状态树模块化的方式,store/index.js 不需要返回 Vuex.Store 实例,直接将 statemutationsactions 暴露出来即可。示例如下:

export const state = () => ({
  accesstoken: ''
})

export const mutations = {
  setAccesstoken (state, accesstoken) {
    state.accesstoken = accesstoken
  }
}

4.6 异步数据 asyncData

Nuxt.js 增加了一个 asyncData 方法,用于 在设置组件数据 之前 能够异步获取 或 处理数据。
由于asyncData 是在组件 初始化 之前被调用的,所以不能通过 this 引用组件的实例对象,可以使用上下文对象来实现某些功能,具体的上下文context

4.7 fetch 方法

asyncData 方法类似,不同的是它不会设置组件的数据,作用是设置store 数据。

5. Nuxt 渲染流程

nuxt-schema.png

上图是nuxt整个的渲染流程,在render之前的几个阶段, 都可以拿到context去做一些相应操作.

  • nuxtServerInit 是Nuxt.js在服务端初始化的时候定义在store中.这个对我们想要直接传递值给服务端非常有用,比如session, user.
  • middleware是一个自定义的方法,在每次渲染页面之前被调用.它可以注册到全局下(nuxt.config.js)也可以注册在单个页面或框架上.
  • validate 允许在动态路由组件中定义一个过滤器方法.
  • asyncDate,fetch asyncData可以让我们在页面绘制前调用方法获取需要的数据源;第一次时在服务端会被调用,之后客户端也会在页面之前被调用.fetchasyncData非常相似,区别只在于fetch只会用来改变store的状态,不能填充数据. *需要的一点.如果在方法中调用this会报错.因为asyncData & fetch在服务端会被调用所以this的当前组件并没有实例化
  • Render 被渲染

6. 一些遇到的坑

  • Window 或 Document 对象未定义?

    这是因为一些只兼容客户端的脚本被打包进了服务端的执行脚本中去。 对于只适合在客户端运行的脚本,需要通过使用 process.browser 变量来判断导入.

  • 服务端渲染v-for 列表

    当页面有列表内容在客户端渲染,刷新页面服务端会重复渲染列表结构,生成两份. 需要用<no-ssr/>组件进行设置,从而不在无武器渲染中呈现

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 目录 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 UI组件 element ★31142...
    吴佳浩阅读 13,740评论 1 61
  • 内容 UI组件 开发框架 实用库 服务端 辅助工具 应用实例 Demo示例 UI组件 element ★13489...
    秋玄语道阅读 14,696评论 3 116
  • 前天老公都下班回来了,大宝去别人家玩还不知道回来,我要下去收衣服,顺便去逮他回来。我刚进那朋友家的们,臭小子便马上...
    红猪猪阅读 4,256评论 0 2
  • 40岁后的你,经历了很多的事,看清了很多的人,品尝了很多的苦,已经进入了不惑之年,没有了青春期的气盛,没有...
    武传华阅读 3,051评论 0 0
  • 闻江湖-其一 孤楼红叶画知秋, 挥剑凤弦一点愁。 沧山纷纭沉江月, 谁饮红尘英雄仇? --------------...
    景黎阅读 1,664评论 0 2