nuxt

想要学习nuxt.js,首先要弄清楚客户端渲染和服务端渲染这两个概念。

一、客户端渲染 VS 服务端渲染

1. 客户端渲染

简单理解就是,在服务端放一个html 页面,客户端发起请求时,服务端把页面(响应的是字符串)发送过去。客户端从上到下依次解析,如果发现ajax请求就再发送新请求,拿到ajax 响应结果以后渲染模板引擎。整个过程至少要发起两次请求。如图:

客户端渲染.png

但是,这种渲染方式存在的弊端也日益显露出来,比如首屏渲染慢,不利于seo等问题。想对应的,服务端渲染恰好弥补了这些不足。

2. 服务端渲染:

也称SSR,即server side render的缩写。在服务端渲染出完整的首屏dom结构,直接发送到浏览器;前端拿到的内容包括首屏及完整spa结构,应用激活后依然按照spa方式运行。整个过程只向服务端发起一次请求。如图:

image.png
服务端渲染有两大优点:

一是更利于SEO。因为爬虫只会爬取源码,不会执行脚本。使用了MVVM框架之后,页面的大多数DOM元素是在客户端根据js动态生成的,可供爬虫抓取分析的内容很少。而且浏览器爬虫不会等数据加载完成之后再去抓取。服务端渲染返回的是已经获取了异步数据并执行JavaScript脚本的最终HTML,爬虫就可以抓取完整的页面信息。
二是更利于首屏渲染。对服务端渲染而言,首屏渲染是node发送过来的html字符串,不依赖于js文件,这样用户就能更快地看到页面内容。尤其是大型单页应用,资源请求量大,造成首屏渲染加载缓慢,使用服务端渲染就可以在很大程度上解决首页的白屏等待问题。
Nuxt.js作为Vue.js的通用框架,就常被用来作SSR。

二、nuxt.js

nuxt是一个专注于ui渲染的应用框架,可以快速搭建项目,还提供了服务端渲染的功能。

1. 安装

直接用vue-cli安装
vue init nuxt-community/starter-template <project-name>

2. nuxt推荐的项目结构

assets——资源文件
components——组件
layouts——布局,默认default。所有页面都会加载在布局页面中的<nuxt />标签中。如果要在普通页面中使用下级路由,则要在页面中添加<nuxt-child />
middleware——中间件:每个页面加载前调用,在页面中调用的方法是middleware: 'middlewareName'。
node_modules——依赖包
nuxt.config.js——个性化配置
package.json——
pages——页面。根页面是index.vue,二级页面只要添加文件夹。动态路由页面的名称格式是:_变量.vue
plugins——插件
static——静态文件(不需要webpack打包的)。
store——状态管理
yarn.lock

3. 生命周期

Nuxt在vue的基础上对生命周期做了扩展:

export defualt {
  middleware(){ }, // 服务端
  validate(){ },  // 服务端
  asyncData(){ },  // 服务端
  fetch(){ },  // store数据加载
  beforeCreate(){ },  // 服务端和客户端都会执行
  created(){ },  //  服务端和客户端都会执行
  beforeMount(){ }, // 
  mounted(){ } // 客户端
}
4. asyncData(context)

如果需要服务端渲染,首次渲染时一定要使用这个方法。它可以在渲染组件前异步获取数据。asyncData传入context参数,可以获取一些信息,如:

export default {
  asyncData(ctx){
    ctx.app   // 根实例
    ctx.route   // 路由实例
    ctx.params   // 路由参数
    ctx.query   // 路由问号后的参数
    ctx.error   // 错误处理方法
  }
}

使用这个方法时要注意,如果由于服务器或api错误导致无法渲染,就要做好容错机制,可以使用context.error方法。我们可以这样做:

async asyncData(ctx){
  try {
    throw new Error()
  } catch {
    ctx.error( {statusCode: 500, message: '服务器开小差了~'} ) // 这里的statusCode参数必须是http状态码
  }
}

此时,错误页可以通过/layout/error.vue自定义。
注意:该方法在服务端执行,返回的数据与data()返回的数据合并。该方法在组件初始化前被调用,所以不能通过this引用实例对象。

5. head()

用于更新头部信息title/descripe等,可以通过this获取组件数据。

6. middleware()

在特定页面实战中间件使用axios请求数据:
(1)nuxt项目默认安装axios,所以只要安装proxy即可

npm install @nuxtjs/proxy

(2)在nuxt.config.js中加上:

export default {
  modules: [
    '@nuxtjs/axios',
    '@nuxtjs/proxy'
  ],
  proxy: {
    './api': {
      target: 'http://www.xxx.com',
      changeOrigin: true,
      pathRewrite: {
        '^/api': ''
      }
    }
  }
}

(3)页面中使用

import axios from 'axios'
export default {
    data () {
        return {
          page: 0
        }
    },
    async asyncData () {
        let data = await axios.get('http://localhost:3000/api/admin/list')
        return {
          page: data.data.page
        }
  },
}

采用 import axios from 'axios' 方式引入axios时,接口参数前须加baseURL。

5. 使用scss

(1)安装sass

npm i node-sass sass-loader scss-loader --save-dev

(2)如果要全局使用某个scss文件,要借助sass-resources-loader,还需要在nuxt.config.js的build配置中调整导出的loader配置:

export default {
  build: {
    extend(config, { isDev, isClient }){
      const sassResourcesLoader = {
        loader: 'sass-resources-loader',
        options: {
          resources: [
            // 填写需要全局注入scss的文件
            'assets/styles/mixins.scss'
          ]
        }
      }
      // 修改 scss sass 引用的 loader。
      config.module.rules.forEach((rule) => {  
        if (rule.test.toString() === '/\\.vue$/') {  
          rule.options.loaders.sass.push(sassResourcesLoader)  
          rule.options.loaders.scss.push(sassResourcesLoader)  
        }  
        if (['/\\.sass$/', '/\\.scss$/'].indexOf(rule.test.toString()) !== -1) {  
          rule.use.push(sassResourcesLoader)  
        }  
      })  
    }
  }
}
6. nuxt和vue的区别

(1)路由
nuxt按照 pages 文件夹的目录结构自动生成路由
vue需在 src/router/index.js 手动配置路由
(2)入口页面
nuxt页面入口为 layouts/default.vue
vue页面入口为 src/App.vue
(3)webpack配置
nuxt内置webpack,允许根据服务端需求,在 nuxt.config.js 中的build属性自定义构建webpack的配置,覆盖默认配置。
vue关于webpack的配置存放在build文件夹下。

7. 编译过程

(1)加载nuxt.config.js;
(2)初始化nuxt,builder,开始执行构建;
(3)准备模板使用的参数,然后根据模板生成真正的webpack编译的js;
(4)分别执行客户端编译和服务端编译,生成最终的js脚本;
(5)编译成功后,就需要启动服务,监听端口,这个是在npm run start中实现的。

关于nuxt.js先写这些了,更多内容还是要去看官网文档哦~

关注微信公众号【CC前端手记】一起学更多前端小知识吧~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,682评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,277评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,083评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,763评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,785评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,624评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,358评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,261评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,722评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,900评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,030评论 1 350
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,737评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,360评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,941评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,057评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,237评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,976评论 2 355

推荐阅读更多精彩内容