感悟
经过几个周六周日的尝试,终于解决了服务端渲染中的常见问题,也成功说服了公司新项目采用前后端分离的解决方案,当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里的组件有fetch
和asyncData
方法,所以当我们使用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>
还有很过好玩的就不说了,文章太长了估计都不想看了
项目部署
大概在8月份时候,写了几篇关于如何部署nodejs项目的文章:
nodejs服务器部署教程一
nodejs服务器部署教程二,把vue项目部署到线上
nodejs服务器部署教程三,部署基于node+vue+mongodb的项目
nodejs服务器部署教程四,部署ssl证书,升级为https
随着时间推移,修复了一些错误,发现了一些错误,整体写的太乱。于是抽了一天时间,在新的服务器上一边实践一边记录,把上面几篇文章用gitbook汇总了一下
结语
不放个demo就走显得就不厚道了,基于Nuxt.js的开源项目确实不太多,以下是我耗时一个月业余时间做的小项目,之前是基于vuejs开发的,现在用Nuxt.js进行了重构,解决了服务端渲染的常见问题
GitHub
GitBook
Nuxt.js服务端渲染实践,从开发到部署
原文地址:http://www.cnblogs.com/yesyes/p/7977161.html