本着学习的目的看了vue-router
和react-router
的代码,于是自己也写了个小 demo。
写着写着。。。想到用 express route 的方式来实现前端路由也许会挺有趣,于是就造了个轮子。。。
在线demo (最好用PC端看)
下面是轮子的一些介绍
目录
基本
SME Router 是仿照 express 的风格编写的,前端路由库。所以 api 跟 express 有点类似。
跟 express 一样,在 SME Router 中,路由和中间件注册的顺序也是非常重要的。先注册的路由会先匹配,先注册的中间件也会先执行。
PS.下面的例子都是用 hash mode 写的。想改成 html5 history 模式,需要 new SMERouter('router-view', 'html5')
。改成 html5 模式后,需要服务器支持。具体配置见 vue-router 后端配置例子
import SMERouter from 'sme-router'
const router = new SMERouter('router-view')
router.route('/user/:id', (req, res, next) => {
const { params, query, body , url, route } = req
console.log(params.id) // output => 123
console.log(query.name) // output => hwen
console.log(body.mes) // output => hallo world
console.log(url) // output => /user/123?name=hwen
console.log(route) // output => /user/:id
})
router.go('/user/123?name=hwen', { mes: 'hallo world'})
模板
你可以使用任何 webpack 支持的 template-loader,因为 res.render
只是简单地插入字符串
下面例子的 webpack 完整配置,可以在 这里 查看
使用前,你应该安装 pug-loader
或 handlebars-loader
1.using pug #demo
因为 pug-loader 在 webpack3 使用有 bug(2017-10-22),所以你应该安装"pug-loader": "~2.2.1"
.
并在 loader 的配置后面加上 ?
,不然还是会报错
webpack config
module: {
rules: [
{
test: /\.pug$/,
loader: 'pug-loader?'
}
}
import pugTemplate from './autumn.pug'
export default function autumn (req, res, next) {
var { params, query, body } = req
res.render(pugTemplate(req))
}
2.using handlebars #demo
webpack config
module: {
rules: [
{
test: /\.hbs$/,
use: {
loader: 'handlebars-loader'
}
}
}
import hbsTemplate from './autumn.hbs'
export default function autumn (req, res, next) {
var { params, query, body } = req
// 你可以使用 handlebars 自定义 json helpers 来处理 json
res.render(hbsTemplate({
paramsStr: JSON.stringify(params),
queryStr: JSON.stringify(query),
bodyStr: JSON.stringify(body),
body: body
}))
}
重定向
重定向需要用到 router.route('*')
import SMERouter from 'sme-router'
const router = new SMERouter('router-view')
router.route('/index', (req, res, next) => {
res.render('hallo world')
})
router.route('*', (req, res, next) => {
res.redirect('/index')
})
router.go('/other') // will be redirected to /index
中间件
中间件添加使用 router.use
,跟路由一样,注册的顺序也是很重要的。中间件会在每个匹配路由的 handler
执行前,先执行一遍
import SMERouter from 'sme-router'
const router = new SMERouter('router-view')
router.use((req) => {
req.body.count += 3
})
router.use((req) => {
req.body.count *= 2
})
router.use((req) => {
req.body.order = `NO.${req.body.count}`
})
router.route('/user/:name', (req, res, next) => {
console.log(req.body.count) // output => 8
console.log(req.body.order) // output => NO.8
})
router.go('/user/Leo', { count: 1 })
二级路由
二级路由需要用到 next()
方法传递下去,以及 res.subRoute()
生成二级页面渲染的节点
import SMERouter from 'sme-router'
const router = new SMERouter('router-view')
router.route('/main', (req, res, next) => {
next(`
<h2>Main title</h2>
${res.subRoute()}
`)
})
router.route('/main/:content', (req, res, next) => {
res.render(
`Iam nested content`
)
})
router.go('/main/sample')