感悟
通過幾個週六週日的嘗試,終於解決了服務端渲染中的常見問題,當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進行了重構!