NUXT SSR初级入门笔记(小结)


Posted in Javascript onDecember 16, 2019

nuxt 是基于 vue 开发的一个应用框架,最常用的就是拿来做 ssr。那么什么是 ssr 呢,这就要提及一个相对的概念:csr。

CSR & SSR

web网页开发从之前的 jsp,php 转向现在的三大框架 angular react vue,其实就是从 csr 到 ssr 的转变,即从服务端渲染转而变为客户端渲染。

有使用经验的大概知道,例如之前的 php 开发,是将网页内容和服务端代码逻辑写在一起的,在客户端请求时,服务端经过 php 引擎的渲染生成完整的 html 页面再返回给客户端,这种渲染出的页面在浏览器中右键查看源代码都是能看见 页面全部的 html 代码的。而客户端渲染如 vue,返回的就只有一个挂在 app 节点的 html文件和一个 js 文件,页面的内容都是在客户端的 js 渲染生成的。所以 渲染 html 文本所在的位置就是 CSR(客户端渲染) 和 SSR(服务端渲染) 最本质的区分 。

既然web开发从 ssr 过渡到了 csr,那我们为什么又再去做 ssr 呢,这就要涉及到双方的优缺了:

SSR:

优点:

便于 SEO,渲染完整的 html 更利于搜索引擎的抓取。

页面加载的白屏时间短(几乎没有)。

缺点:

每加载一个页面都要对服务器发起一次请求,服务器的渲染负荷重,请求缓慢。

每次加载都会刷新页面,即使只是页面中的小区域需要改变。

CSR:

优点:

页面具有优秀的性能,更利于页面交互。

缺点:

不利于SEO

首页初始化加载白屏时间长。

在我们普遍使用三大框架的今天,如果我们的页面需要对 SEO 的良好支持,这就需要我们做 ssr 了。 NUXT 项目的初始化

使用以下命令调用脚手架生成项目,脚手架选项按需选择就可以了:

npx create-nuxt-app <项目名>

生成的目录结构如下:

NUXT SSR初级入门笔记(小结) 

.nuxt

运行缓存目录

assets

资源目录,用于存放如 css 文件,js 文件,图片

components

组件目录,用于存放 vue 组件

layouts

布局目录,用于设置布局,文件名即为布局名

在 pages 目录里的组件可以通过 layout 属性指定布局组件,不指定默认为 default。

布局组件中使用 <nuxt /> 标签指定应用布局时,page 组件所在的位置。

middleware

中间件目录,用于设置中间件函数,文件名即为中间件名

在 pages 目录里的组件可以通过 middleware 属性指定中间件函数,中间件会在组件渲染前执行

pages

页面目录,用于设置路由页面,目录下的 vue 文件会自动生成相应的路由配置

如以下目录结构对应的配置:

pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue

router: {
 routes: [
  {
   name: 'index',
   path: '/',
   component: 'pages/index.vue'
  },
  {
   name: 'users-id',
   path: '/users/:id?',
   component: 'pages/users/_id.vue'
  },
  {
   name: 'slug',
   path: '/:slug',
   component: 'pages/_slug/index.vue'
  },
  {
   name: 'slug-comments',
   path: '/:slug/comments',
   component: 'pages/_slug/comments.vue'
  }
 ]
}

nuxt 中使用 <nuxt-link> 代替了 <router-link>

nuxt 会为 page 组件提供额外的配置项,常用到的如下:

  • layout 指定当前页面使用的布局(layouts 根目录下的布局文件)。
  • validate 校验方法用于校验动态路由的参数。
  • middleware 指定页面的中间件函数,中间件函数会在页面渲染之前被调用,也可以指定为middleware文件夹内的中间件名。
  • asyncData 支持异步数据处理,拿来为 page 组件请求异步数据,返回对象中的 data 会覆盖到组件的 data 中。
  • fetch 用于在渲染页面之前获取数据填充应用的状态树(store)。不同的是 fetch 方法不会设置组件的数据。

plugins

插件目录,用于引入第三方模块,

如 element-ui.js:

import Vue from 'vue'
import Element from 'element-ui'
import locale from 'element-ui/lib/locale/lang/en'

Vue.use(Element, { locale })

然后可以在 nuxt.config.js 中的 plugins 中引入:

plugins: [
  '@/plugins/element-ui'
 ],

server

服务端目录

static

静态文件目录

store

vuex目录,index.js 为主文件,其他文件默认会配置成 module 模块,默认启用 namespace。

文件形式为:

export const state = () => ({
  // state
})

export const actions = {
  // actions
}

export const mutations = {
  // mutations
}

在 index.js 的 actions 中可以配置 nuxtServerInit,可以用来将数据从服务端传到客户端。

具体使用

创建项目如下:

NUXT SSR初级入门笔记(小结)

运行初始项目,效果如下:

NUXT SSR初级入门笔记(小结) 

使用布局

在 layouts 下新建文件 myLayout.vue

<template>
 <div>
  <header>
   <h2>I am header</h2>
  </header>
  <main>
   <nuxt />
  </main>
  <footer>
   <h2>I am footer</h2>
  </footer>
 </div>
</template>

然后我们在 pages 下新建文件 layoutDemo.vue

<template>
 <div>
  <h1>I am layout demo</h1>
 </div>
</template>

<script>
export default {
 layout: 'myLayout'
}
</script>

访问 localhost:3000/layoutDemo,布局效果如下:

NUXT SSR初级入门笔记(小结) 

使用中间件

例如我们实现一个未登录拦截跳转的中间件:

在 middleware 中新建 auth.js

export default function (ctx) {
 // eslint-disable-next-line no-constant-condition
 if (true) { // ctx 判断得到未登录
  ctx.redirect({ path: '/' })
 }
}

再在 layoutDemo.vue 中加上 middleware: 'auth' ,这样访问该页面就会拦截跳转回主页面。

用 asyncData 实现 ssr

我们再在 pages 中新建页面 ssr1.vue

<template>
 <div>
  <ul>
   <li v-for="item of list1" :key="item">
    {{ item }}
   </li>
  </ul>
  <ul style="margin-top: 50px">
   <li v-for="item of list2" :key="item">
    {{ item }}
   </li>
  </ul>
 </div>
</template>

<script>
export default {
 layout: 'myLayout',
 data () {
  return {
   list1: []
  }
 },
 async created () {
  const { status, data: { list } } = await this.$axios.get('/list')
  if (status === 200) {
   this.list = list
  }
 },
 async asyncDate () {
  const { status, data: { list } } = await this.$axios.get('/list')
  if (status === 200) {
   return {
    list2: list
   }
  }
 }
}
</script>

这里我们 list1 是用传统的 vue 方式获取异步数据, list2 用 asyncData 获取异步数据

然后我们在 server 中写接口,应为 node 还是采用 require 的方式,如果我们想使用 import 的方式,可以安装 babel-cli 和 babel-preset-env , 新建配置文件 .babelrc:

{
 "presets": ["env"]
}

然后在 package.json 里将 dev 命令加上后缀 --exec babel-node , server 中书写 node 就可以使用 import 了。

然后安装 koa-router,在 index.js 里加入以下代码:

import Router from 'koa-router'

// 以下代码加在 start 函数内的 原有的 app.use 之前
const router = new Router()
router.get('/list', (ctx) => {
ctx.body = {
 list: ['a', 'b', 'c']
}
})
app.use(router.routes()).use(router.allowedMethods())

然后访问页面,两个列表都正常渲染

NUXT SSR初级入门笔记(小结)

我们右键查看源代码:

NUXT SSR初级入门笔记(小结)

list2 通过 asyncData 的方式实现了 ssr。

使用 nuxtServerInit 实现 ssr

我们新建页面 ssr2.vue

<template>
 <div>
  <ul>
   <li v-for="item of $store.state.list" :key="item">
    {{ item }}
   </li>
  </ul>
 </div>
</template>

<script>
export default {
 layout: 'myLayout'
}
</script>

然后在 store 中新建 index.js

export const state = () => ({
 list: []
})

export const mutations = {
 setList (state, value) {
  state.list = value
 }
}

export const actions = {
 async nuxtServerInit ({ commit }, { app }) {
  const { status, data: { list } } = await this.$axios.get('/list')
  if (status === 200) {
   commit('setList', list)
  }
 }
}

重新 npm run dev, 访问 localhost:3000/ssr2

NUXT SSR初级入门笔记(小结)

查看源代码,也正确渲染

NUXT SSR初级入门笔记(小结)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
一端时间轮换的广告
Jun 26 Javascript
JavaScript在多浏览器下for循环的使用方法
Nov 07 Javascript
jQuery之日期选择器的深入解析
Jun 19 Javascript
js修改input的type属性问题探讨
Oct 12 Javascript
JQuery的Ajax中Post方法传递中文出现乱码的解决方法
Oct 21 Javascript
浅谈jquery中delegate()与live()
Jun 22 Javascript
跟我学习javascript的定时器
Nov 19 Javascript
深入理解jQuery之防止冒泡事件
May 24 Javascript
细说webpack源码之compile流程-rules参数处理技巧(1)
Dec 26 Javascript
vue-cli webpack模板项目搭建及打包时路径问题的解决方法
Feb 26 Javascript
JavaScript中的E-mail 地址格式验证
Mar 28 Javascript
js实现京东秒杀倒计时功能
Jan 21 Javascript
js实现内置计时器
Dec 16 #Javascript
js实现秒表计时器
Dec 16 #Javascript
在vue中使用axios实现post方式获取二进制流下载文件(实例代码)
Dec 16 #Javascript
js实现计时器秒表功能
Dec 16 #Javascript
原生Vue 实现右键菜单组件功能
Dec 16 #Javascript
axios如何取消重复无用的请求详解
Dec 15 #Javascript
Vue在chrome44偶现点击子元素事件无法冒泡的解决方法
Dec 15 #Javascript
You might like
php简单的上传类分享
2016/05/15 PHP
php rsa 加密,解密,签名,验签详解
2016/12/06 PHP
PHP实现表单提交时去除斜杠的方法
2016/12/26 PHP
PHP实现用户异地登录提醒功能的方法【基于thinkPHP框架】
2018/03/15 PHP
JavaScript 不只是脚本
2007/05/30 Javascript
基于jquery中children()与find()的区别介绍
2013/04/26 Javascript
基于jquery和svg实现超炫酷的动画特效
2014/12/09 Javascript
javascript实现数独解法
2015/03/14 Javascript
跟我学习javascript的循环
2015/11/18 Javascript
javascript小数精度丢失的完美解决方法
2016/05/31 Javascript
javascript使用闭包模拟对象的私有属性和方法
2016/10/05 Javascript
jQuery焦点图左右转换效果
2016/12/12 Javascript
javascript算法之二叉搜索树的示例代码
2017/09/12 Javascript
详解JavaScript实现动态的轮播图效果
2019/04/29 Javascript
Vue+axios+WebApi+NPOI导出Excel文件实例方法
2019/06/05 Javascript
layui 选择列表,打勾,点击确定返回数据的例子
2019/09/02 Javascript
微信小程序网络请求实现过程解析
2019/11/06 Javascript
python3序列化与反序列化用法实例
2015/05/26 Python
Python实现在线音乐播放器
2017/03/03 Python
基于Python pip用国内镜像下载的方法
2018/06/12 Python
pygame游戏之旅 调用按钮实现游戏开始功能
2018/11/21 Python
python3+selenium实现126邮箱登陆并发送邮件功能
2019/01/23 Python
Python为何不能用可变对象作为默认参数的值
2019/07/01 Python
pytorch::Dataloader中的迭代器和生成器应用详解
2020/01/03 Python
Python中itertools的用法详解
2020/02/07 Python
python3.7+selenium模拟淘宝登录功能的实现
2020/05/26 Python
使用ITK-SNAP进行抠图操作并保存mask的实例
2020/07/01 Python
Big Green Smile法国:领先的英国有机和天然产品在线商店
2021/01/02 全球购物
犹他州最古老的体育用品公司:Al’s
2020/12/18 全球购物
介绍一下Make? 为什么使用make
2016/07/31 面试题
会计职业生涯规划书
2014/01/13 职场文书
教育技术职业规划范文
2014/03/04 职场文书
小学教师自我鉴定范文
2014/03/20 职场文书
Golang Gob编码(gob包的使用详解)
2021/05/07 Golang
python 爬取京东指定商品评论并进行情感分析
2021/05/27 Python
分享一个vue实现的记事本功能案例
2022/04/11 Vue.js