感悟

经过几个周六周日的尝试,终于解决了服务端渲染中的常见问题,当SEO不在是问题的时候,或许才是我们搞前端的真正的春天,其中也遇到了一些小坑,Nuxt.js官方还是很给力的,提issue后很积极的给予帮助,再次感谢Nuxt.js的开发团队。

项目地址
演示地址

路由鉴权

第一个拦路虎就是登陆时候的鉴权问题,如何把token保存到本地。官方使用express-session解决这个问题,但是这样做后端也需要使用nodejs,而我们公司使用的PHP。转念一想或许cookie可以一试,于是我是这样做的:

app.post('/api/login', function (req, res) {
// 后台验证用户信息,并返回token
async function login () {
const { data } = await axiosServer.post('/login', req.body)
return data
} login().then(function (data) {
// 把token存储到cookie中
const { token } = data
if (token) {
res.cookie('token', token, {
maxAge: 60000 * 60 * 24
})
}
// 原封不动返回
return res.json(data)
})
})

我把登录请求用nodejs做了一次转发,把用户提交的数据传给后端,后端返回的token设置到cookie里,然后把数据返会给前端,前端再用vuex保存token状态,这样token同时存在于cookie和内存里,刷新页面也是正常的
前端存储token:

  async nuxtServerInit ({ dispatch, commit }, { req, res }) {
if (req.cookies && req.cookies.token) {
// 存储token
commit('SET_USER', req.cookies.token)
}
},
// SET_USER
SET_USER (state, token) {
state.token = token
},

于是这个问题就这样解决了,所有需要存储到本地的数据都可以这样做来解决

渲染组件内的数据

另一个小问题是components里数据如何渲染。在Nuxt.js中只有page里的组件有fetchasyncData方法,所以当我们使用layout布局页面时如果组件需要请求数据,就无法渲染了,解决方法是在nuxtServerInit方法里初始化组件内的数据,如下:

  async nuxtServerInit ({ dispatch, commit }, { req, res }) {
// 初始化组件内的数据
await dispatch('ADMIN_INFO')
await dispatch('TAGS')
await dispatch('ARCHIVES')
}

这样组件内的数据也可渲染成功了

过滤器的使用

Nuxt.js的plugins设计的个人感觉还是很人性化的,用起来简直是不能再简单。在plugins新建一个filters.js,过滤器可以这样玩:

import Vue from 'vue'
// 时间格式化
export function formatDate (date, fmt) {
let newDate = new Date(date)
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (newDate.getFullYear() + '').substr(4 - RegExp.$1.length))
}
let o = {
'M+': newDate.getMonth() + 1,
'd+': newDate.getDate(),
'h+': newDate.getHours(),
'm+': newDate.getMinutes(),
's+': newDate.getSeconds()
}
for (let k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
let str = o[k] + ''
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str))
}
}
return fmt
}
let filters = {
formatDate
} Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
export default filters

然后在nuxt.config.js中注册一下:

  plugins: [
'~plugins/filters.js'
]

在组件中就可以这样happy的用起来了:

<!-- 时间格式化 -->
<div>
<span>{{date | formatDate('yyyy-MM-dd')}}</span>
</div>

中间件

比如说用户未登录状态下,通过路由闯入了需要鉴权的页面,我们可以自定义一些错误:

// auth.js
export default function ({ store, error }) {
// 可通过组件的props接收error信息
if (!store.state.token) {
error({
message: 'cookie失效或未登录,请登录后操作',
statusCode: 403
})
}
}

在组件中使用该中间件:

export default {
middleware: 'auth',
// 还可以把用户重定位到登录页
fetch ({redirect, store}) {
if (!store.state.token) {
redirect('/login')
}
},
}

多级路由嵌套

官方说这种情况用的较少,但是我发现用的挺多的,比如说不同分类又有不同分页,这样分类和分页都要是动态路由,如图所示:

编译后的结果:

项目部署

大概在8月份时候,写了几篇关于如何部署nodejs项目的文章,回头看写的果然比较菜,随着时间推移,修复了一些错误,发现了一些错误,整体写的太乱。于是抽了一天时间,在新的服务器上一边实践一边记录,把上面几篇文章用gitbook汇总了一下,不在这里展开了,太长了,增加了自动部署的相关内容

结语

以上所有的实践代码都在这里,这个小项目是我在几月前写的,后来用Nuxt.js进行了重构!

Nuxt.js服务端渲染实践,从开发到部署的更多相关文章

  1. nuxt.js服务端渲染中less的配置和使用

    第一步:npm 安装 less 和 less-loader ,文件根目录下安装,指令如下 npm install less less-loader --save-dev 第二步:直接在组件中使用 &l ...

  2. next.js、nuxt.js等服务端渲染框架构建的项目部署到服务器,并用PM2守护程序

    前端渲染:vue.react等单页面项目应该这样子部署到服务器 貌似从前几年,前后端分离逐渐就开始流行起来,把一些渲染计算的工作抛向前端以便减轻服务端的压力,但为啥现在又开始流行在服务端渲染了呢?如v ...

  3. nuxt项目服务端渲染应用部署、使用pm2守护进程及遇到的问题处理

    服务端渲染应用部署应该先编译构建,然后再启动 Nuxt 服务,可通过以下两个命令来完成: nuxt build nuxt start 我们已经在pakage.json里配置好script命令 { &q ...

  4. ASP.NET Core 与 Vue.js 服务端渲染

    http://mgyongyosi.com/2016/Vuejs-server-side-rendering-with-aspnet-core/ 原作者:Mihály Gyöngyösi 译者:oop ...

  5. NET Core 与 Vue.js 服务端渲染

    NET Core 与 Vue.js 服务端渲染 http://mgyongyosi.com/2016/Vuejs-server-side-rendering-with-aspnet-core/原作者: ...

  6. Vue.js 服务端渲染业务入门实践

    作者:威威(沪江前端开发工程师) 本文原创,转载请注明作者及出处. 背景 最近, 产品同学一如往常笑嘻嘻的递来需求文档, 纵使内心万般拒绝, 身体倒是很诚实. 接过需求,好在需求不复杂, 简单构思 后 ...

  7. vue.js 服务端渲染nuxt.js反向代理nginx部署

    vue.js的官方介绍里可能提到过nuxt.js,我也不太清楚我怎么找到这个的 最近项目vue.js是主流了,当有些优化需求过来后,vue还是有点力不从心, 比如SEO的优化,由于vue在初始化完成之 ...

  8. nuxt.js服务端缓存lru-cache

    对于部分网页进行服务端的缓存,可以获得更好的渲染性能,但是缓存又涉及到一个数据的及时性的问题,所以在及时性和性能之间要有平衡和取舍. 官方文档里面写的使用方法 按照这个配置,试过了没什么用,但是从文档 ...

  9. Nuxt.js vue服务端渲染

    一.为什么要用Nuxt.js 原因其实不用多说,就是利用Nuxt.js的服务端渲染能力来解决Vue项目的SEO问题. 二.Nuxt.js和纯Vue项目的简单对比 1. build后目标产物不同 vue ...

随机推荐

  1. 非关系型数据库redis

    Redis初始 redis中不区分字母的大小写 查看端口 ss tnlp 安装 编译安装(需要先配置epel源) yum install -y redis 编译安装 wget https://down ...

  2. Spring Cloud Gateway 不小心换了个 Web 容器就不能用了,我 TM 人傻了

    个人创作公约:本人声明创作的所有文章皆为自己原创,如果有参考任何文章的地方,会标注出来,如果有疏漏,欢迎大家批判.如果大家发现网上有抄袭本文章的,欢迎举报,并且积极向这个 github 仓库 提交 i ...

  3. LGP3708题解

    题面很直白,就不说了罢qaq 首先很明显,\(\sum_{i=1}^n x \bmod i = nx - \sum_{i=1}^n i\lfloor \frac x i \rfloor\) 这道题要是 ...

  4. LGP4451题解

    题意明确,不再阐述( 首先,众所周知的是 斐波那契数列 的生成函数是 \(F(x)=\frac x {1-x-x^2}\) 那么答案就是 \(\sum_{i=0} F^i(x) = \frac 1 { ...

  5. egg启动时,报错:Ignoring invalid timezone passed to Connection的解决方案

    报错信息 Ignoring invalid timezone passed to Connection: +8:00. This is currently a warning, but in futu ...

  6. 企业网络防范Serv-U的漏洞

    很多企业都将自己的网站建立在互联网上,日常有专门的维护人员进行维护,很多时候对网站的更新当然不是直接在服务器上操作,而是将要更新的网页页面通过FTP工具上传到服务器上实现.因此必须要在服务器上搭建起一 ...

  7. Java基础——final、static关键字

    final关键字是最终的意思,可以修饰成员方法.成员变量.类 特点: 1.修饰方法:表示该方法是最终方法,不能被重写 2.修饰变量:表示变量是常量,不能再次被赋值 3.修饰类:表示类是最终类,不能被继 ...

  8. new和@Autowired的区别

    controller层: @RequestMapping("/payment") @RestController public class WxPayController { pu ...

  9. 6月22日 Django中ORM的F查询和Q查询、事务、QuerySet方法大全

    一.F查询和Q查询 F查询 在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较.如果我们要对两个字段的值做比较,那该怎么做呢? Django 提供 F() 来做这样的比较.F() 的实 ...

  10. 深度学习工具LabelXml安装教程

    LabelXml安装教程 1,下载LabelXml工具 前往github上下载labelxml,官网地址如下:https://github.com/tzutalin/labelImg 下载打包源码为z ...