淺談在koa2中實現(xiàn)頁面渲染的全局數(shù)據(jù)
最近用koa2做一個項目的web端,遇到一個場景。
該項目主要用的是傳統(tǒng)的服務端渲染的方式,所以會用 koa-views 去做頁面的渲染工作。實現(xiàn)方式就是 ctx.render('path',data),那么,有如下場景,每個頁面都需要去驗證是否登錄,登錄了要返回頁面?zhèn)€人數(shù)據(jù),這個情況,怎么辦呢?我不想每次都去手動的加入個人數(shù)據(jù)啊。例如這樣:
let data = { "user":"12", "questionList":questionList }; await ctx.render("index",data);
此處的user就是每個頁面都是要返回的數(shù)據(jù)。
很顯然,每個頁面都要獲得的數(shù)據(jù),用中間件去獲取,類似java的攔截器,過濾器之類的了。
import {UserClient} from "../manager/user/UserClient"; export const signInStatusMiddleware = async (ctx:any,next:any)=>{ console.log("signInStatusMiddleware") let accessToken = ctx.cookies.get("ACCESS-TOKEN"); if(accessToken){ let userClient :UserClient = new UserClient; let user = await userClient.getUserByToken(accessToken); } await next(); }
OK,中間件中已經(jīng)拿到了用戶數(shù)據(jù)了,那么,問題來了。數(shù)據(jù)是可以拿,怎么放呢?
找到koa-views 源碼。有如下代碼:
return function views(ctx, next) { if (ctx.render) return next() ctx.render = function(relPath, locals = {}) { return getPaths(path, relPath, extension).then(paths => { const suffix = paths.ext const state = Object.assign(locals, options, ctx.state || {}) // deep copy partials state.partials = Object.assign({}, options.partials || {}) debug('render `%s` with %j', paths.rel, state) ctx.type = 'text/html' if (isHtml(suffix) && !map) { return send(ctx, paths.rel, { root: path }) } else { const engineName = map && map[suffix] ? map[suffix] : suffix const render = engineSource[engineName] if (!engineName || !render) return Promise.reject( new Error(`Engine not found for the ".${suffix}" file extension`) ) return render(resolve(path, paths.rel), state).then(html => { ctx.body = html }) } }) } return next() }
關(guān)鍵是這一段
const state = Object.assign(locals, options, ctx.state || {})
很顯然,state 是將傳入的數(shù)據(jù),合并了,中間件配置的options ,和ctx.state的。中間件顯式配置顯然部合適,所以,做法是,在攔截器中間件中,把user賦值給ctx.state.
export const signInStatusMiddleware = async (ctx:any,next:any)=>{ console.log("signInStatusMiddleware") let accessToken = ctx.cookies.get("ACCESS-TOKEN"); if(accessToken){ let userClient :UserClient = new UserClient; let user = await userClient.getUserByToken(accessToken); ctx.state = Object.assign(ctx.state,{"user":user}); } await next(); }
ok。這樣一來,在頁面渲染的時候,就會帶上用戶信息了。而不需要再在各處去自己手動添加。
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
better?sqlite3安裝node?gyp原生模塊編譯prebuild-install
這篇文章主要為大家介紹了Nodejs關(guān)于原生模塊編譯node-gyp?+?prebuild-install?(以安裝?better-sqlite3為例)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11利用node.js實現(xiàn)自動生成前端項目組件的方法詳解
最近在學習用,基于nodejs的強大,我從原本的只寫前端變成了寫全棧。下面這篇文章主要給大家介紹了關(guān)于利用node.js實現(xiàn)自動生成前端項目組件的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友們下面來一起看看吧。2017-07-07Node.js中使用事件發(fā)射器模式實現(xiàn)事件綁定詳解
這篇文章主要介紹了Node.js中使用事件發(fā)射器模式實現(xiàn)事件綁定詳解,本文一并講解了回調(diào)模式、發(fā)射器模式、事件類型等基礎(chǔ)知識做了補充,需要的朋友可以參考下2014-08-08Linux 安裝nodejs環(huán)境及路徑配置詳細步驟
大家都知道linux安裝nodejs有兩種比較常用的方法,一種解壓即可用的方法操作比較簡便,另一種方法通過編譯來安裝,本文重點給大家講解第一種方法,感興趣的朋友跟隨小編一起看看吧2021-11-11