preface
Angular, React, and Vue are the three front-end frameworks. Their routing solutions Angular/Router, React – Router, and VUE-Router are all implemented based on front-end routing principles. Therefore, it is necessary to understand and master front-end routing principles. Once we understand how it works, we’ll be able to use it more easily in development.
What is routing?
The concept of routing originated from the server. In the past, when the front and back ends were not separated, the back end controlled routing. When receiving the HTTP request from the client, it would find the corresponding mapping function according to the corresponding URL requested, and then execute the function and send the return value of the function to the client. For the simplest static resource server, you can think of the mapping function of all urls as a file read operation. For dynamic resources, the mapping function may be a database read operation, some data processing, and so on. Then according to these read data, the server side will use the corresponding template to render the page, and then return the rendered page. Its advantages and disadvantages are obvious:
- Benefits: Good security,
SEO
Good; - Disadvantages: increase the server pressure, is not conducive to user experience, code redundancy is not good maintenance;
It is because of the shortcomings of back-end routing that front-end routing has its own development space. For front-end routes, the route mapping function usually does some DOM show and hide operations. In this way, different page components are displayed when accessing different paths. Front-end routing mainly has the following two implementation schemes:
Hash
History
Of course, front-end routing has its drawbacks: using the browser’s forward and back keys to re-send requests to retrieve data does not make proper use of caching. In general, front-end routing is now the main way to implement routing. The three front-end frameworks Angular, React and Vue, and their routing solutions Angular/Router, React-Router and VUe-Router are all developed based on front-end routing. Therefore, it is necessary to understand and master front-end routing. In the following sections, two common front-end routing modes Hash and History are explained respectively.
Two implementations of front-end routing
2.1. Hash Mode
2.1.1, principle
Early implementations of front-end routing were based on location.hash. The implementation principle is simple: the value of location.hash is the content after the # in the URL. For example, here’s a website whose location.hash value is ‘#search’ :
https://www.word.com#search
Copy the code
In addition, hash has the following features:
URL
中hash
Value is just a state on the client side, which means that when a request is made to the server side,hash
Parts will not be sent.hash
Any change in value adds a record to the browser’s access history. So we can control it through the browser’s back and forward buttonshash
The switch.- We can use
hashchange
Event to listenhash
The change.
There are two ways to trigger the hashchange. One is to use the a tag and set the href attribute. When the user clicks on the tag, the URL will change and the hashchange event will be triggered:
<a href="#search">search</a>
Copy the code
Alternatively, you can assign to loaction.hash directly in JavaScript to change the URL and trigger the hashchange event:
location.hash="#search"
Copy the code
The following implementation is implemented in the second way.
2.1.2, implementation,
Let’s start by defining a parent class BaseRouter that implements some common methods for Hash and History routes.
export class BaseRouter {
// list indicates the routing table
constructor(list) {
this.list = list;
}
// page rendering function
render(state) {
let ele = this.list.find(ele= > ele.path === state);
ele = ele ? ele : this.list.find(ele= > ele.path === The '*'); ELEMENT.innerText = ele.component; }}Copy the code
We have simply implemented the push function and go forward/backward function. The annotations of relevant codes have been marked, which are easy to understand and will not be introduced one by one. Please refer to the following:
export class HashRouter extends BaseRouter {
constructor(list) {
super(list);
this.handler();
// Listen for the hashchange event
window.addEventListener('hashchange', e => {
this.handler();
});
}
// Re-render the page when the hash changes
handler() {
this.render(this.getState());
}
// Get the hash value
getState() {
const hash = window.location.hash;
return hash ? hash.slice(1) : '/';
}
// Push a new page
push(path) {
window.location.hash = path;
}
// Get the default page URL
getUrl(path) {
const href = window.location.href;
const i = href.indexOf(The '#');
const base = i >= 0 ? href.slice(0, i) : href;
return base +The '#'+ path;
}
// Replace the page
replace(path) {
window.location.replace(this.getUrl(path));
}
// Scan history forward or backward
go(n) {
window.history.go(n); }}Copy the code
2.1.3 Effect drawing
The Hash route implementation example is as follows:
2.2. History Mode
2.2.1, principle
The previous hash is also a good one, but it doesn’t look pretty when you use it. So in HTML5, there’s a History API to implement URL changes. The two main apis are history.pushstate () and history.repalcestate (). Both apis allow you to manipulate the browser’s history without refreshing it. The only difference is that the former is to add a history, while the latter is to replace the current history directly, as shown below:
window.history.pushState(null.null, path);
window.history.replaceState(null.null, path);
Copy the code
In addition, history has the following features:
pushState
和repalceState
The title of the (title
) : The general browser will ignore, the best passnull
;- We can use
popstate
Event to listenurl
The change of the; history.pushState()
或history.replaceState()
Not triggerpopstate
Event, in which case we need to manually trigger the page rendering;
2.2.2, implementation,
We have also simply implemented the push function and go forward/backward function. The annotations of relevant codes have been marked, which are easy to understand and will not be introduced one by one. Please refer to the following:
export class HistoryRouter extends BaseRouter {
constructor(list) {
super(list);
this.handler();
// Listen for popState events
window.addEventListener('popstate', e => {
console.log('Trigger popState... ');
this.handler();
});
}
// Render the page
handler() {
this.render(this.getState());
}
/ / get the url
getState() {
const path = window.location.pathname;
return path ? path : '/';
}
/ / push page
push(path) {
history.pushState(null.null, path);
this.handler();
}
/ / the replace page
replace(path) {
history.replaceState(null.null, path);
this.handler();
}
// Scan history forward or backward
go(n) {
window.history.go(n); }}Copy the code
2.2.3 Effect drawing
An example of routing implementation in History mode looks like this:
2.3 Comparison of the two routing modes
Contrast point | Hash pattern | The History mode |
---|---|---|
Beautiful sex | With the # character, ugly | Concise and beautiful |
compatibility | >= Ie 8, other major browsers | >= Ie 10, other major browsers |
practical | No changes to the server are required | The server needs to coordinate the route Settings |
Third, summary
In this article, we briefly introduced the routing, the origin of front-end routing, and analyzed the principle and simple function implementation of two front-end routing modes: Hash mode and History mode. The code implementation of the examples in this article has been posted on Github: github.com/fengshi123/… . In this article, you can read the source code of vue-Router and React-Router based on the principle of front-end routing.
The github address is github.com/fengshi123/… If you like it or are inspired by it, please help to give it a star ~, which is also an encouragement to the author.
reference
1, the introduction to the front-end routing: www.jianshu.com/p/d2aa8fb95…
2, the front-end routing: segmentfault.com/a/119000001…