服務端渲染 Node 層直接獲取數據
在 Egg 項目如果使用模板引擎規范時通是過 render 方法進行模板渲染,render 的第一個參數模板路徑,第二個參數時模板渲染數據. 如如下調用方式:
async index(ctx) { // 獲取數據,可以是從數據庫,后端 Http 接口 等形式 const list = ctx.service.article.getArtilceList(); // 對模板進行渲染,這里的 index.js 是 vue 文件通過 Webpack 構建的 JSBundle 文件 await ctx.render('index.js', { list });}
從上面的例子可以看出,這種使用方式是非常典型的也容易理解的模板渲染方式。在實際業務開發時,對于常規的頁面渲染也建議使用這種方式獲取數據沒,然后進行頁面渲染。Node 獲取數據后,在 Vue 的根 Vue 文件里面就可以通過 this.list 的方式拿到 Node 獲取的數據,然后就可以進行 vue 模板文件數據綁定了。
在這里有個高階用法,可以直接把 ctx 等 Node 對象傳遞到 第二個參數里面, 這個時候你在模板里面就直接拿到 ctx 這些對象。 但這個時候就需要自己處理好 SSR 渲染時導致的 hydrate 問題,因為前端hydrate時并沒有 ctx 對象。
async index(ctx) { // 獲取數據,可以是從數據庫,后端 Http 接口 等形式 const list = ctx.service.article.getArtilceList(); // 對模板進行渲染,這里的 index.js 是 vue 文件通過 Webpack 構建的 JSBundle 文件 await ctx.render('index.js', { ctx, list });}
服務端渲染 asyncData 方式獲取數據
在 Vue 單頁面 SSR 時涉及數據的請求方式,Node 層獲取數據方式可以繼續使用,但當路由切換時(頁面直接刷新),Node 層就需要根據路由獲取不同頁面的數據,同時還要考慮前端路由切換的情況,這個時候路由是不會走 Node 層路由,而是直接進行的前端路由,這個時候也要考慮數據的請求方式。
基于以上使用的優雅問題,這里提供一種 asyncData 獲取數據的方式解決單頁面 SSR 刷新不走 SSR 問題。 Node 不直接獲取數據,獲取數據的代碼直接寫到前端代碼里面。這里需要解決如下兩個問題:
前端路由匹配 asyncData 調用
這里根據路由切換 url 獲取指定的路由 componet 組件,然后檢查是否有 aysncData,如果有就進行調用。調用之后,數據會放到 Vuex 的 store 里面。
return new Promise((resolve, reject) => { router.onReady(() => { // url 為當前請求路由,可以通過服務端傳遞到前端頁面 const matchedComponents = router.getMatchedComponents(url); if (!matchedComponents) { return reject({ code: '404' }); } return Promise.all( matchedComponents.map(component => { // 關鍵代碼 if (component.methods && component.methods.asyncData) { return component.methods.asyncData(store); } return null; }) ).then(() => { context.state = { ...store.state, ...context.state }; return resolve(new Vue(options)); }); }); });
Vue 模板定義 asyncData 方法
前端通過 Vuex 進行數據管理,把數據統一放到 store 里面,前端通過 this.$store.state 方式可以獲取數據,Node 和 前端都可以獲取到。
<script type="text/babel"> export default{ computed: { isLoading(){ return false; }, articleList() { return this.$store.state.articleList; } }, methods: { asyncData ({ state, dispatch, commit }) { return dispatch('FETCH_ARTICLE_LIST') } } }</script>
新聞熱點
疑難解答