感悟
通过几个周六周日的尝试,终于解决了服务端渲染中的常见问题,当SEO不在是问题的时候,或许才是咱们搞前端的真正的春天,其中也遇到了一些小坑,Nuxt.js官方仍是很给力的,提issue后很积极的给予帮助,再次感谢Nuxt.js的开发团队。javascript
路由鉴权
第一个拦路虎就是登录时候的鉴权问题,如何把token保存到本地。官方使用express-session解决这个问题,可是这样作后端也须要使用nodejs,而咱们公司使用的PHP。转念一想或许cookie能够一试,因而我是这样作的:vue
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:java
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 },
因而这个问题就这样解决了,全部须要存储到本地的数据均可以这样作来解决node
渲染组件内的数据
另外一个小问题是components里数据如何渲染。在Nuxt.js中只有page里的组件有fetch
和asyncData
方法,因此当咱们使用layout布局页面时若是组件须要请求数据,就没法渲染了,解决方法是在nuxtServerInit
方法里初始化组件内的数据,以下:ios
async nuxtServerInit ({ dispatch, commit }, { req, res }) { // 初始化组件内的数据 await dispatch('ADMIN_INFO') await dispatch('TAGS') await dispatch('ARCHIVES') }
这样组件内的数据也可渲染成功了git
过滤器的使用
Nuxt.js的plugins设计的我的感受仍是很人性化的,用起来简直是不能再简单。在plugins新建一个filters.js,过滤器能够这样玩:github
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中注册一下:web
plugins: [ '~plugins/filters.js' ]
在组件中就能够这样happy的用起来了:vuex
<!-- 时间格式化 --> <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进行了重构!