原生路由
要想实现原生路由,需要得到地址栏输入的路径,然后根据路径的不同进行跳转。用ctx.request.url和switch判断就可以实现。
app.use((ctx)=>{
switch(ctx.url){
case '/':
console.log("你在访问根路径");
break;
case '/index':
console.log("你在访问index路径");
break;
case '/todo':
console.log("你在访问todo路径");
break;
case '/404':
console.log("没有此路径");
break;
default:
break;
}
})
但这样子是远远不能满足业务需求的,于是我们使用中间件koa-router
koa-router中间件
- 引入中间件koa-router:
const Router = require('koa-router');
- 使用中间件koa-router:
app.use(router.routes()).use(router.allowedMethods());
举个例子
// add url-route:
router.get('/hello/:name', async (ctx, next) => {
var name = ctx.params.name;
ctx.response.body = `<h1>Hello, ${name}!</h1>`;
});
router.get('/', async (ctx, next) => {
ctx.response.body = '<h1>Index</h1>';
});
往往我们处理路由时有层级的概念,比如‘/home’开头的路由交给子路由home去处理,‘/sign’开头的路由交给子路由sign去处理。
层级路由
const Koa = require('koa');
const app = new Koa();
const Router = require('koa-router');
let home = new Router();
home.get('/jspang',async(ctx)=>{
ctx.body="Home JSPang";
}).get('/todo',async(ctx)=>{
ctx.body ='Home ToDo';
})
let sign = new Router();
sign.get('/jspang',async(ctx)=>{
ctx.body="sign JSPang";
}).get('/todo',async(ctx)=>{
ctx.body ='sign ToDo';
})
//装载所有子路由
let router = new Router();
router.use('/home',home.routes(),home.allowedMethods());
router.use('/page',page.routes(),page.allowedMethods());
//加载路由中间件
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000,()=>{
console.log('[demo] server is starting at port 3000');
});
使用了层级路由后,我们可以把业务逻辑很好的分离开来。
但是这里有存在一个新的问题:所有的路由都写在index.js文件中,使得代码结构杂乱
为了解决这个问题,我们重新组织一下代码结构
路由总分结构
如上图所示,我把所有的路由代码都抽离在router目录下
在router目录下存放了三个js文件
index.js //总路由表
sign.js //子路由表sign
home.js //子路由表home
index.js中的代码
const sign = require('./sign.js');
const home = require('./home.js');
module.exports = {
sign,
home
}
sign.js中的代码
const Router = require('koa-router');
const sign = new Router();
sign.get('/',async(ctx)=>{
await ctx.render('sign',{title:"sign"});
if(ctx.cookies.get('place')){
ctx.cookies.set('place','sign over');
}else{
ctx.cookies.set('place','sign');
}
}).get('/cs',async(ctx)=>{
ctx.body = "Sign cs";
});
module.exports = sign;
入口文件index.js
const Koa = require('koa');
const Router = require('koa-router');
const BodyParser = require('koa-bodyparser');
const Static = require('koa-static');
const views = require('koa-views');
const routers = require('./router');
const path = require('path');
const app = new Koa();
const router = new Router();
//使用模板ejs
app.use(views(path.join(__dirname,'./views/'),{extension:'ejs'}));
//路由表
app.use(router.routes()).use(router.allowedMethods());
router.use('/sign',routers.sign.routes(),routers.sign.allowedMethods());
router.use('/home',routers.home.routes(),routers.home.allowedMethods());
//post解析
app.use(BodyParser());
//黑洞路由
app.use(Static(path.join(__dirname,'./static/')));
//端口监听
app.listen(80);
这样子做,结构清晰,逻辑清晰
参考文章
技术胖的博客