- demo
- github
Train of thought
So far only hash has been implemented. The whole idea is that we have a main file, router.js, in which we define two methods, use and route
Use pushes all middleware into the Router’s middleware array. In the route method, we call the this._matcher addRoutes method. This._matcher is actually an instance of createMatcher.
route(path, controller){
// Execute all middleware before executing controller
// Add all routes and their controller to _matcher
this._matcher.addRoutes(path, (req) => {
this._middlewares.forEach(fn= > {
fn(req)
});
Router: this * callback(req, res) */
console.log("It's coming in......")
controller&&controller(req, this)})}Copy the code
CreateMatcher’s job is to reorganize all the routing rules in the configuration file and parse the URLS we request every time. Its match method is used to parse this URL. But the match method is called inside HashHistory. Because our Router was passed to it when it was instantiated. And assign the instantiated value to this._history
this._history = this._mode === 'hash'
? new HashHistory({matcher: this._matcher})
: new Html5History({matcher: this._matcher});
Copy the code
AddRoutes receives a path and a handler, which is all middleware in the routing configuration file and the controller for each route in app.route(Path, Controller). Path is regularized to match every URL on our app page and pushed into createMatcher’s _routes.
_toReg regularizes the path of route(Path, controller).
addRoutes(path, handler){
let routeReg = this._toReg({
path: path,
handler: handler,
params: []});this._routes.push(routeReg);
}
Copy the code
How do we intercept a request? Actually the word intercept is not quite accurate. In HashHistory, we use _setListener to listen for hash changes.
_setListener(){
window.addEventListener('load'.this._refresh);
window.addEventListener('hashchange'.this._refresh);
}
Copy the code
When we go from page A to page B, we do so by clicking on the link above page A, which has an onclick event, and the parameter in go is our request URL.
<li onclick="app.go('/order/fruit? Price =100&time=now', {message: 'order '})">The order</li>
Copy the code
When we click on it, we actually change the window.location.hash value first (the click event triggers the go method first). This. _cache[URL] = body stores the information we want to pass in. For example, get the value of the current form.
go(url, body){
this._cache[url] = body;
console.log("come here........")
window.location.hash = `${url}`;
}
/ /... //
_getHash (){
/ / reference Vue - the router
// window.location.hash is unstable and Firefox will release a new version
const href = window.location.href;
const index = href.indexOf(The '#');
return index === - 1 ? ' ' : href.slice(index + 1)}Copy the code
Once the hash has been modified, our onHashchange event can listen in and trigger the _refresh method, which calls _getHash, gets the hash value, and then calls the Match method of createMatcher that was passed in. Parse the path(which is actually the URL mentioned above); When parsed, a matchedRoutes is returned. This matchedRoutes not only contains the param parsed, but also contains the handler for the route (the handler includes middleware and the controller for the route).
this._refresh = (a)= > {
// Every time the hash changes, get the changed hash
console.log("Refesh! ...")
const path = this._getHash();
const matchedRoutes = this.matcher.match(path);
this._matchedCount = matchedRoutes.length;
this._fireHandlers(matchedRoutes, this._cache[path]);
}
Copy the code
_fireHandlers are the final call handler and the final function that handles the request.
_fireHandlers(matchedRoutes, body) {
console.log("I am the best one")
for (let i = 0; i < matchedRoutes.length; i++) {
// The matched route contains controllers to be executed
const item = matchedRoutes[i];
// Construct the request body
const request = {
body: body || {},
query: item.query,
params: item.params
};
def(request, 'route', item.path);
def(request, 'url', item.url);
item.handler(request)
}
}
Copy the code
reference
Many thanks to sme-Router author!
From his code, I learned a lot and deepened my understanding of vue-Router.
- [email protected]
- sme-router
- Different ways to realize front-end routing