var Koa = require('koa');
var Router = require('koa-router');
var app = new Koa();
var router = new Router();
router.get('/home',(ctx,next)=>{
ctx.body = 'home'
next();
});
router.get('/user', (ctx, next) => {
ctx.body = 'user';
next();
});
app.use(router.routes()).use(router.allowedMethods());
複製代碼
var Koa = require('koa');
var Router = require('koa-router');
var app = new Koa();
var router = new Router();
//將路由的處理交給中間件
app.use((ctx, next) => {
if (ctx.path === '/' && ctx.method === 'GET') {
ctx.body = '首頁'
} else {
next();
}
})
app.use((ctx, next) => {
if (ctx.path === '/user' && ctx.method === 'GET') {
ctx.body = '用戶'
} else {
next();
}
});
複製代碼
從上面能夠知道,若是沒有koa-router,其實每一個路由使用的koa註冊中間件的形式來進行處理的,這樣不利於鬆耦合和模塊化,因此將全部路由的處理邏輯抽離出來組合成一個大的中間件koa-router來處理,最後將大的中間件註冊到koa上,若是關於koa中間件原理還不瞭解,能夠參考另外一篇文章koa框架會用也會寫—(koa的實現)css
既然koa-router也是大的中間件,裏面擁有許多小的中間件,那麼裏面必然也須要用到洋蔥模型,洋蔥模型的特色:html
若是對於中間件和洋蔥模型有疑問的,能夠參考koa框架會用也會寫—(koa的實現)mysql
class Router {
constructor(){
this.middles=[];
}
}
module.exports = Router
複製代碼
class Router {
constructor(){
this.middles=[];
}
get(path,fn){//set,post等同理
let layer = {
path,
fn,
method
}
//處理相似/article/:id的路由
if(path.includes(':')){
let params = [];
let reg = path.replace(/:([^\/]*)/g,function () {
params.push(arguments[1]); //params = [id]
return '([^\/]*)' //返會字符串/article/([^\/]*)
});
//將返回的字符串變成正則,後面解析路由是會用到
layer.reg = new RegExp(reg);//返回/\/article\/([^\/]*)/
layer.params = params;
}
this.middles.push(layer);
}
}
module.exports = Router
複製代碼
class Router {
constructor(){
this.middles=[];
}
get(path,fn){//set,post等同理
let layer = {
path,
fn,
method
}
//處理相似/article/:id的路由
if(path.includes(':')){
let params = [];
let reg = path.replace(/:([^\/]*)/g,function () {
params.push(arguments[1]); //params = [id]
return '([^\/]*)' //返會字符串/article/([^\/]*)
});
//將返回的字符串變成正則,後面解析路由是會用到
layer.reg = new RegExp(reg);//返回/\/article\/([^\/]*)/
layer.params = params;
}
this.middles.push(layer);
}
compose(lasts,next,ctx){//lasts爲匹配的路由集合
dispatch(index){
if(index === lasts.length) return next();
let route = lasts[index];
//將路徑參數都取出來exp:id的值
let params = route.params;
let [, ...args] = pathname.match(route.reg);
ctx.request.params = params.reduce((memo,key,index)=>(memo[key] = args[index], memo), {});
//執行路由邏輯,next賦值爲下一個路由邏輯
route.fn(ctx,()=>{
dispatch(index+1);
})
}
dispatch(0)
}
}
module.exports = Router
複製代碼
class Router {
constructor(){
this.middles=[];
}
get(path,fn){//set,post等同理
let layer = {
path,
fn,
method
}
//處理相似/article/:id的路由
if(path.includes(':')){
let params = [];
let reg = path.replace(/:([^\/]*)/g,function () {
params.push(arguments[1]); //params = [id]
return '([^\/]*)' //返會字符串/article/([^\/]*)
});
//將返回的字符串變成正則,後面解析路由是會用到
layer.reg = new RegExp(reg);//返回/\/article\/([^\/]*)/
layer.params = params;
}
this.middles.push(layer);
}
compose(lasts,next,ctx){//lasts爲匹配的路由集合
dispatch(index){
if(index === lasts.length) return next();
let route = lasts[index];
route.fn(ctx,()=>{
dispatch(index+1);
})
}
dispatch(0)
}
routes() {
// ctx上下文next指的是koa中的next方法
return async (ctx, next) => {
let pathname = ctx.path; //請求的路徑
let lasts = this.middles.filter(item => {
if (route.reg) { // 說明當前路由是一個路徑參數
if (method === route.method && route.reg.test(pathname)) {
return true //路徑參數匹配到了,添加進路由組
}
}
if ((method === route.method || route.method === 'all') && (route.p === pathname || route.p === '*')) {
return true //路徑是'/'或者'all',添加進路由組
}
return false;
});
this.compose(lasts, next, ctx);
}
}
}
module.exports = Router
複製代碼
上面的router是簡化版的koa-router,它只實現了koa-router中的一級路由,可是倒是能說明koa-router的主要思想,koa-router中添加了use來註冊二級路由,同時添加了不少包括重定向等其餘邏輯處理sql
koa-router中間件的原理基本就介紹完了,後面一塊兒學習kao的其餘中間件:數據庫