精读《Nuxtjs》

1 引言

Nuxt 是基于 Vue 的前端开发框架,此次咱们经过 Introduction toNuxtJS 视频了解框架特点以及前端开发框架的基本要素。javascript

nuxt 与 next 结构很像,能够结合在一块儿看css

视频介绍了 NuxtJs 的安装、目录结构、页面路由、导航模版、asyncData、meta、vueX。html

这是一个入门级视频,因此上面所列举的特征都是一个前端开发框架的最核心的基本要素。一个前端开发框架,安装、目录结构、页面路由、导航模版必定是最要下功夫认真设计的。前端

asyncData 和 Vuex 都在解决数据问题,meta 则是经过约定语法控制网页 meta 属性,这部分值得与 React 体系作对比,在精读部分再展开。vue

Nuxtjs 前端开发框架不只提供了脚手架的基本功能,还对项目结构、代码作了约定,以减小代码量。从这点能够看出,脚手架永远围绕两个核心目标:让每一行源码都在描述业务逻辑;让每一个项目结构都相同且易读java

20 年前,几百行 HTML、Css、Js 代码就能完成一个完整的项目,只须要遵照 W3C 的基本规范就足够了,每个项目代码都简单清晰,并且因为没有复杂的业务逻辑,致使代码结构也很是简单。但如今前端项目复杂度逐渐升高,一个大型项目源码数量可能达到几十万行、几百万行,这是 W3C 规范没有设想到的,所以出现了各类工程化与模块化方案解决这个复杂度问题,也引起了各个框架间约定的割裂,且设计合理程度各不相同。react

Nuxtjs 等框架要作的就是定义支持现代大型项目的前端研发标准,这个规范具备网络效应,即用的人越多,价值越大。ios

接下来咱们进入正题,看看 Nuxt 脚手架定义了怎样的开发规范。git

2 概述

安装

使用 npx create-nuxt-app app-name 建立新项目。这个命令与 create-react-app 同样,区别主要是模版以及配置不一样。程序员

这个命令本质上是拉取一个模版到本地,并安装 nuxt 系列脚本做为项目依赖,并自动生成一系列 npmScripts:

{
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "test": "jest"
  },
  "dependencies": {
    "nuxt": "^2.0.0"
  }
}
复制代码

以后便可经过 npm start 等命令开发项目,对大部分项目来讲,npmScripts 启动是最能达成共识的。

这种安装方式另外一个好处是,依赖都被安装在了本地,即开发环境 100% 内置在项目中。Nuxt 没有采用全局 cli 命令方式执行,第一是 npmScripts 更符合你们通用习惯,不须要记住不一样脚手架繁琐的名称与不一样约定的启动命令,第二是全局脚手架一旦进行不兼容升级,老项目就面临维护难题。

目录结构

├── .nuxt
├── layouts
├── pages
├── store
├── assets
├── static
├── middleware
├── plugins
├── nuxt.config.js
复制代码

pages

页面文件存放的目录,路径 + 文件名即路由名,关于更多约定路由的信息,在下一节页面路由详细说明。

layouts

模版文件存放的目录,文件名即模版名,页面能够经过定义模版在选择使用的模版。

store

全局数据流目录,在 vueX 章节介绍。

assetsstatic

分别存放不需被编译的资源文件与非 .vue 的静态文件,好比 scss 文件。

因为 .vue 文件集成了 html、js、css,所以通常不会再额外定义样式文件在 static 文件夹中。

固然,这是 Vue 生态的特别之处,在 React 生态中会存在大量 .scss 文件混杂在各个目录中,比较影响阅读。

middlewareplugins

中间件与插件,这两个目录是可选的,做为一种定制化拓展能力。

.nuxt

为实现约定路由等便捷功能,启动项目时须要自动生成一些文件做为真正项目入口,这些文件就存储在 .nuxt 目录下,gitingore 且无需手动修改。

nuxt.config.js

nuxt 使用 js 文件做为配置文件,比 json 配置文件拓展性更好一些,这个文件也是整个项目惟一的配置文件。

基本上 pageslayoutsstoreassets、以及惟一的配置文件基本成为现代前端开发框架的标配。

页面路由

nuxt 支持约定路由:

├── pages
│   ├── home.vue
│   └── index.vue
复制代码

上述目录结构描述了两个路由://home

也支持参数路由,只要如下划线做为前缀命名文件,就定义了一个动态参数路由:

├── pages
│   ├── videos
│   │   └── _id.vue
复制代码

/videos/* 都会指向这个文件,且能够经过 $route.params.id 拿到这个 url 参数。

另外一个特性是嵌套路由:

├── pages
│   ├── videos
│   │   └── index.vue
│   └── videos.vue
复制代码

videos.vuevideos/index.vue 都指向 /videos 这个路由,若是这两个文件同时存在,那么外层的 videos 就会做为外层拦截全部 /videos 文件夹下的路由,能够经过 nuxt-child 透出子元素:

# pages/videos.vue
<template>
  <div>
    videos
    <nuxt-child />
  </div>
</template>
复制代码

导航模版

页面公共逻辑,好比导航条能够放在模版里,模版的目录在 layouts 文件夹下。

默认 layouts/default.vue 对全部页面生效,但也能够建立例如 layouts/videos.vue 特殊导航文件,在 pages/ 页面文件经过以下申明指定使用这个模版:

<script> export default { layout: "videos" }; </script>
复制代码

asyncData

asyncData 是 nuxt 支持的异步取数函数,能够替代 data

data 函数:

<script> export default { data() { return {}; } }; </script>
复制代码

对于异步场景,能够用 asyncData 替代:

<script> export default { async asyncData() { return await fetch("/"); } }; </script>
复制代码

meta

nuxt 容许在 .vue 页面文件自定义 head 标签信息:

<script> export default { headr() { return { title: "", meta: { charset: "utf-8" } }; } }; </script>
复制代码

这是开发框架提供的特性,不过在 React 体系下能够经过 useTitle 等自定义 Hooks 解决此问题,将框架功能降维到代码功能,会更容易理解些。

vueX

nuxt 集成了 vuex,在 store/ 文件夹下建立数据模型:

export const state = () => ({
  videos: [],
  currentVideo: {}
})

export const mutations = {
  SET_VIDEOS (state, videos) {
    state.videos = videos
  }
  SET_CURRENT_VIDEO (state, video) {
    state.currentVideo = video
  }
}
复制代码

接下来就能在 pages 文件夹下的页面组件使用了:

<script> import { mapState } from "vuex"; export default { async fetch({ $axios, params, store }) { const reponse = await $axios.get(`/videos/${params.id}`); const video = response.data.data.arrtibutes; store.commit("SET_CURRENT_VIDEO", video); } }; </script>
复制代码

return 替换为 store.commit 便可,更多语法能够参考 vuex 文档

3 精读

Nuxtjs 框架作了几件事情:

  1. 统一执行命令。
  2. 统一开发框架。
  3. 统一目录与代码规范。
  4. 内置公共 utils 函数。

统一执行命令

命令行是全部开发者天天都要用上十几回甚至几十次的场景,试想一下团队中项目分别有以下这么多不一样的启动命令会怎么样?

  1. npm start.
  2. monkey dev.
  3. npm run ng.
  4. npm run bootstrap & banana start.
  5. ...

我永远不知道下一个项目该如何启动,这大大下降了开发效率。更严重的是,有的项目能够经过 npm run docs 查看文档,有的项目不能;有的项目 npm run build 能够触发编译,有的项目却无需编译,等等,所谓的环境不一致或者说迁移成本,学习成本,都是由最开始负责搭建项目脚手架的同窗对架构设计不一致致使的,然而没有必须用 monkey dev 才能运行起来的项目,但项目却可能由于被设计为 monkey dev 启动而显得与其余项目格格不入,甚至难以统一维护。

Nuxtjs 等前端开发框架统一执行命令就是为了解决这个问题,统一开发者习惯须要很长的时间周期,但这个趋势不可挡。

统一开发框架

虽然如今 React、Vue、Angular 框架各有利弊,但若是一个团队的项目同时使用了两个以上的框架,没有人会以为这是一件好事。

诚然每一个框架都有本身的特色,在不一样维度都一些优点,但三大框架能并存,说明各自都没有绝对的杀手锏来消灭对方。

对开源来讲,多元化是活力的源动力,但对一家公司来讲,多元化就是一场灾难,至今没有一个框架敢说本身的优点是 “与其余框架混合使用能够提高总体开发效率”。

前端开发框架要解决的最重要问题也是这一点,不管如何只能选择一种开发框架,Nuxtjs 选择了 Vue,Nextjs 选择了 React。

统一目录与代码规范

目录和代码规范不会从根本上影响项目的通用性,由于不一样的目录结构能够经过映射来兼容,不一样的代码规范不会影响代码执行。因此目录与代码规范真正影响的是一个程序员对项目的 “解码成本”。

所谓解码成本,就是程序员理解项目逻辑所须要的成本。若是你是一个销售主管,让团队周报统一用一种格式汇总绝对比 “用本身喜欢的方式汇总” 效率高,而对编程也同样,一个彻底不一样的目录结构和代码规范对程序员来讲是巨大的阅读阻碍,甚至可能引起恶心反应。

因此不一样的目录结构和代码规范是没有必要的壁垒,除非你的团队已经对某种规范产生达成了牢固的共识,不然最好和其余团队共享相同的目录结构与代码规范。改变代码规范是一件很可贵事情,但只要不一样规范的团队间产生了长期合做关系,规范统一就势必会被提上议程,那么为什么不能在公司层面早一点达成共识,提早消除这种痛苦呢?

因此统一目录与代码规范是前端开发框架须要优先肯定的,不少时候不要去质疑为何目录叫 layouts 而不叫 layout,由于这个规范背后造成的协同网络规模越大,叫什么名字就越不重要。

内置公共 utils 函数

让业务开发更聚焦,还能够经过抽取通用的逻辑的方式解决,但须要解决两个问题:

  1. 虽然将公共函数抽成 npm 包能够解决代码复用问题,但关键是怎么保证你的代码能被别人复用?
  2. 如何让业务通用的 utils 代码有效沉淀并从项目中移除?

脚手架内置公共 utils 函数就为了解决这个问题。上面几个小节解决了通用命令、框架、规范,但实际代码中,router history fetch store 等等概念也都是能够统一的,没有一个项目必须用定制的 fetch 函数才能取数,但一开始就定制了 fetch 会致使耦合了不可预期的、没有必要的业务逻辑,成为理解与提效的阻碍。

因此统一这些能统一的包,是进一步提效的关键。也许有人会以为断了本身造轮子的路,但就像咱们现在都不会重写浏览器内核逻辑同样,稳定的逻辑不只带来了全行业的提效,还催生了前端岗位带来大量的就业,一样的,统一底层通用函数,实际上是断了无心义产出这条路,每一个人都有追求更高价值事情的权利,不要把本身困在反复造 fetch 函数这个低水平的活里。

4 总结

若是一个项目没有使用相似 Nuxtjs 开发框架,它面临的不只仅是技术选型不统一的问题,长此以往这种项目势必成为 代码孤岛,当尘封在代码仓库几年后,一系列文档工具连接都失效后,就成为谁也不想碰,不敢碰的高危代码。

因此咱们今天不只要看到 Nuxtjs 提供的能力对项目开发有多么便捷,更要看到这类框架带来的协同效应有多么巨大,若是它不能成为整个前端的标准,至少要成为大家公司,或者大家团队的标准。

讨论地址是:精读《Nuxtjs》 · Issue #213 · dt-fe/weekly

若是你想参与讨论,请 点击这里,每周都有新的主题,周末或周一发布。前端精读 - 帮你筛选靠谱的内容。

关注 前端精读微信公众号

版权声明:自由转载-非商用-非衍生-保持署名(创意共享 3.0 许可证

相关文章
相关标签/搜索