Home > Article > Web Front-end > Detailed explanation of the routing implementation principle of vuejs
This article brings you a detailed explanation of the routing implementation principle of vuejs. It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
In general source code, window.history and location.hash are used
history implementation
The window.history object contains the history of the browser, and the window.history object is used when writing You do not need to use the window prefix. History is a mainstream method for implementing SPA front-end routing. It has several original methods:
history.back()
The same as clicking the back button in the browserhistory.forward()
Same as clicking the button forward in the browserhistory.go(n)
Accept an integer as a parameter and move to the page specified by the integer. For example, go(1) is equivalent to forward(), go(-1) is equivalent to back(), go(0) is equivalent to refreshing the current page
If The moved position exceeds the boundary of the access history. The above three methods do not report an error, but fail silently
In HTML5, the history object proposes the pushState() method and replaceState() method. These two methods can Used to add data to the history stack, just as if the url has changed (in the past, only the url changed and the history stack would change), so that the browsing history and forward and backward can be well simulated. The current front-end routing is also based on this principle. of.
pushState(stateObj, title, url) method writes data to the history stack. Its first parameter is the data object to be written (not larger than 640kB). The second parameter is the title of the page, and the third parameter is the url (relative path).
stateObj: A state object related to the specified URL. When the popstate event is triggered, the object will be passed into the callback function. If this object is not needed, null can be filled in this *.
title: The title of the new page, but all browsers currently ignore this value, so null can be filled in here.
url: The new URL must be in the same domain as the current page. Your browser's address bar will display this URL.
Regarding pushState, there are several things worth noting:
The pushState method will not trigger a page refresh, but will cause the history object to change, and the address bar will react. Only when events such as forward and backward are triggered (back () and forward(), etc.)
The URL here is restricted by the same-origin policy to prevent malicious scripts from imitating other website URLs to deceive users, so when the same-origin policy is violated, an error will be reported
The difference between replaceState(stateObj, title, url) and pushState is that it does not write but replaces and modifies the current record in the browsing history. The rest is exactly the same as pushState.
Definition: Whenever the browsing history of the same document (that is, the history object) changes, the popstate event will be triggered.
Note: Simply calling the pushState method or replaceState method will not trigger this event. It will only be triggered when the user clicks the browser's back button and forward button, or uses JavaScript to call the back, forward, and go methods. In addition, this event only targets the same document. If the switching of browsing history causes different documents to be loaded, this event will not be triggered.
Usage: When using, you can specify a callback function for the popstate event. The parameter of this callback function is an event object, and its state attribute points to the state object provided by the pushState and replaceState methods for the current URL (that is, the first parameter of these two methods).
<a class="spa">abc.html</a> <a class="spa">123.html</a> <a href="/rdhub" class="spa ">rdhub</a> // 注册路由 document.querySelectorAll('.spa').forEach(item => { item.addEventListener('click', e => { e.preventDefault(); let link = item.textContent; if (!!(window.history && history.pushState)) { // 支持History API window.history.pushState({name: 'history'}, link, link); } else { // 不支持,可使用一些Polyfill库来实现 } }, false) }); // 监听路由 window.addEventListener('popstate', e => { console.log({ location: location.href, state: e.state }) }, false) popstate监听函数里打印的e.state便是history.pushState()里传入的第一个参数,在这里即为{name: 'history'}
hash
Basic introduction to hash
The url can contain a hash http://localhost :9000/#/rdhub.htmlThere is an event in the window object is onhashchange. This event will be triggered in the following situations:
Change the browser address directly, at the end Add or change #hash;
By changing the value of location.href or location.hash;
By triggering a click on an anchored link ;
Moving the browser forward or backward may cause the hash to change, provided that the hash values in the two web page addresses are different.
<a href="/rdhub" class="spa">rdhub</a> <a href="/abc" class="spa">abc</a> <a href="/123" class="spa">123</a> <a href="/hash" class="spa">hash</a> document.querySelectorAll('.spa').forEach(item => { item.addEventListener('click', e => { e.preventDefault(); let link = item.textContent; location.hash = link; }, false) }); // 监听路由 window.addEventListener('hashchange', e => { console.log({ location: location.href, hash: location.hash }) }, false)
hash mode and history mode, these two modes are implemented through the browser interface, except In addition, vue-router also prepares an abstract mode for non-browser environments. The principle is to use an array stack to simulate the function of the browser history stack. Of course, the above are just some core logic. To ensure the robustness of the system, there is a lot of auxiliary logic in the source code, which is also worth learning.
The new URL set by pushState can be any URL that has the same origin as the current URL; while hash can only modify the part after #, so it can only be set with The current URL of the same document
The new URL set by pushState can be exactly the same as the current URL, which will also add the record to the stack; and the new value set by the hash must be different from the original to trigger the addition of the record to the stack Medium
pushState can add any type of data to the record through stateObject; while hash can only add short strings
pushState can additionally set the title attribute for subsequent use
We know that for single-page applications, the ideal usage scenario is to only load index.html when entering the application, and subsequent network operations are completed through Ajax, and will not be based on The URL re-requests the page, but it is inevitable to encounter special circumstances, such as the user directly typing in the address bar and pressing Enter, the browser restarts and reloads the application, etc.
Hash mode only changes the content of the hash part, and the hash part will not be included in the HTTP request:
http://rdhub.cn/#/user/id // Such as The re-request will only send http://rdhub.cn/
, so there will be no problem when requesting a page based on the URL in hash mode.
The history mode will modify the URL to be the same as the normal request backend URL
http://rdhub.cn/user/id
In this case, resend the request to the backend , if the backend is not configured with routing processing corresponding to /user/id, a 404 error will be returned.
The officially recommended solution is to add a candidate resource on the server that covers all situations: if the URL does not match any static resources, it should return the same index.html page, which is what your app depends on. page. At the same time, after doing this, the server will no longer return a 404 error page, because the index.html file will be returned for all paths. To avoid this, cover all routing situations in the Vue application and then give a 404 page. Or, if you use Node.js as the backend, you can use server-side routing to match the URL, and return 404 when no route is matched, thereby implementing fallback.
The above is the detailed content of Detailed explanation of the routing implementation principle of vuejs. For more information, please follow other related articles on the PHP Chinese website!