Skip to content

Instantly share code, notes, and snippets.

@pocotan001
Last active December 20, 2016 11:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pocotan001/8c3bdd5050e8c8a0ed9cc98418b1aa3e to your computer and use it in GitHub Desktop.
Save pocotan001/8c3bdd5050e8c8a0ed9cc98418b1aa3e to your computer and use it in GitHub Desktop.
client router
import Router from './Router'
const router = new Router({
'/': () => { console.log('/') },
'/user/:id': ({ params }) => { console.log('/user/:id', params.id) }
})
router.dispatch()
import pathToRegexp from 'path-to-regexp'
import queryString from 'query-string'
export default class Route {
/**
* @param {string} path
* @param {Function} handler
*/
constructor (path, handler) {
this.path = path
this.handler = handler
this.keys = []
this.regexp = pathToRegexp(path, this.keys)
}
/**
* Checkes whether this route matches the given `location`
* https://github.com/pillarjs/path-to-regexp/blob/master/Readme.md#parameters
*
* @param {Object=location} location
* @returns {Object|null}
*/
match ({ pathname, search } = location) {
const matches = this.regexp.exec(pathname)
if (!matches) {
return null
}
// extract the matched path params
const params = this.keys.reduce((params, { name }, i) => {
const value = matches[i + 1]
// don't overwrite a previously populated parameter with `undefined`
if (value !== undefined && params[name] === undefined) {
params[name] = decodeURIComponent(value)
}
return params
// create an object with no prototype
}, Object.create(null))
const query = queryString.parse(search)
return { params, query }
}
}
import Route from './Route'
export default class Router {
/**
* @param {Object.<string, Function>} routes
*/
constructor (routes) {
this.routes = Object.keys(routes).map((path) => new Route(path, routes[path]))
}
/**
* Dispatch the given `location`
*
* @param {Object=location} location
*/
dispatch (location = location) {
for (let route of this.routes) {
const matched = route.match(location)
if (matched) {
route.handler(matched)
break
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment