“This is the third day of my participation in the First Challenge 2022, for more details: First Challenge 2022”.
background
A few days ago, the interviewer asked me if I could talk about the two modes of vue-router: #/path and /path. The interviewer smiled a little, hehe, talked a little surface, the deep place did not say, good guy, VUe-Router is ambushed my hand, so this article will take you to vue-Router these two modes of pants out to have a look
What’s the use of #?
What impressed me most was the Hash mode of vue-router. When switching, the root directory is followed by a # character, so why did I select it?
First, let’s talk about the meaning of #
- On behalf of the position
# can be used as an anchor to mark the location of an element, and a element can be used as a jump
<a href="#xxx">Jump to XXX position</a>
<! -... Suppose there are many elements in the middle.... -->
<div id="xxx"></div>
Copy the code
Does that fit well with routing or navigation when we click on a page?
- Browser URL ‘not recognized’ #
# not the child of the browser URL
- When sending an HTTP request, # and the character following it are not recognized, are not included in the request parameters, are not considered the request URL, and are not sent to the server
- In the URL field of the current page in the browser, click
#
+ any character and press Enter will not trigger a page reload, because the browser will assume that you want to jump to somewhere on the current page - The Google Spider ignores the content after the #, meaning that content sites are routed to pages that are not picked up and recommended for search by Google’s browsing engine. Is that why vue-Router 4 says that Hash mode is bad for SEO
So what does # do in vue-Router?
The browser also provides an onHashchange event, which allows you to listen for changes in the route and link them to the browser’s forward and backward actions
So vue-Router’s hash # character is not a myth, but a native API provided by the browser
The difference between hash and History modes
Since it is a detailed solution, it is sure to scratch the source code to see, vue-Router choose different mode is how to deal with it? (Compared with vue-Router 3 and 4)
The first is the vue – router3
export default class VueRouter {...constructor (options: RouterOptions = {}) {...switch (mode) {
case 'history':
this.history = new HTML5History(this, options.base)
break
case 'hash':
this.history = new HashHistory(this, options.base, this.fallback)
break
case 'abstract':
this.history = new AbstractHistory(this, options.base)
break
default:
if(process.env.NODE_ENV ! = ='production') {
assert(false.`invalid mode: ${mode}`)}}}... }Copy the code
As you can see, the history and Hash modes are associated with HTML5History and HashHistory, HTML5History uses the pushState and replaceState methods provided by History. HashHistory uses the Hashchange event listener. Can you guess how vue-Router4 implements the hash mode
// I'm a history mode shell
import { createWebHistory } from './html5'.export function createWebHashHistory(base? : string) :RouterHistory {...return createWebHistory(base)
}
Copy the code
Since Vue-Router4 is directly open to hash mode, we’ll only take a peek at the source code for Vue-Router3
Both hash and history modes need to implement routing functions, namely, the following two cores
- Changing the URL does not cause a refresh
- Detects URL changes in the following ways
- Browser Forward and Back
- A The hyperlink of the label changed
- Window. The location change
Changing the URL does not cause a refresh
hash
For the first one, the hash mode takes the form of # + path, changing the URL but the browser doesn’t reload it
At the code level, this is a change to window.location.hash
// vue-router/src/history/hash.js 139
function pushHash(path) {
if (supportsPushState) {
pushState(getUrl(path));
} else {
window.location.hash = path; }}Copy the code
history
Calling the pushState and replaceState methods in History also does not cause a page refresh
history.pushState(state, title[, url])
For details on the parameters, please refer to the MDN documentation
// Jump to the login page
history.pushState(null.""."login");
Copy the code
Detect URL changes
hash
Hash to monitor the hashchange events in vue – the router/SRC/history/hash. 49 lines of js setupListeners method, set up a listener
export class HashHistory extends History {... setupListeners () {const eventType = supportsPushState ? 'popstate' : 'hashchange'
window.addEventListener( eventType, handleRoutingEvent ) ... }}Copy the code
history
Needless to say, you should know the popState event in the source code above
So in a policy to detect CHANGES in urls, hash is listening for a Hashchange event, and history is listening for a popState event
A method to change the URL
window.location
Hash modiates window.location.hash to modify the URL, whereas history does not
A label
(by default), in hash mode, you can click on the link directly, because there is a # anchor mark, but history should prevent the link, otherwise it will send a request to the server. Call pushState/replaceState
Browser Forward and Back
Go,back, and forward calls are both valid because both hash and history are added to the history stack
conclusion
For hash and history, the hash method was used before 2014. History is a new API for HTML5. In the future, history should be used more frequently. You can refer to the hash mode of Vue-Router4 and directly open it to yes
The resources
Vue – the router hash pattern
Router router implementation principle