Implementation principles of hash and history

Since the Vuc project is a single-page application, there is only one physical HTML file during the development and construction process of the entire project. The routing system allows you to bind project components to accessible URL paths. Since the Vue project has only one physical HTML file, the accessed URL path needs to change when switching pages, and the reloading of the physical HTML file cannot be triggered. This makes the page jump mode of VueRouter unable to use ordinary hyperlinks.
In order to support page management and page jumps in single-page applications, VueRouter provides two page jump and loading modes:

(1)hash mode

The hash mode uses anchor point technology to rewrite the URL access path, and will splice /#/xxx after the original URL path. This method can achieve the purpose of switching the URL path without reloading the original HTML file. An implementation example of the principle of hash mode, the code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Routing in hash mode</title>
  <style>
    .page {
      width: 400px;
      height: 400px;
    }
    .about {
      background-color: antiquewhite;
      display: none;
    }
    .index {
      background-color: antiquewhite;
      display: none;
    }
  </style>
</head>
<body>
  <a href="#/index">Visit homepage</a>
  <a href="#/about">Visit the original About page</a>
  <div class="page index">
    I am the homepage
  </div>
  <div class="page about">
    i am about page
  </div>
  <script type="text/javascript">
    //Hash part of url switching event
    window.onhashchange = function (event) {
      //Writing two means that the new one is displayed and the old one is hidden when jumping.
      // Get the url path to be redirected and intercept the page name
      var newURL = event.newURL.split('#/')[1]
       // Get the starting page path when jumping and intercept the page name
       var oldURL = event.oldURL.split('#/')[1]
      // Get the DOM objects of the two pages
      var newPage = document.querySelector('.' + newURL)
      var oldPage = document.querySelector('.' + oldURL)
      //Display target page
      newPage.style.display = 'block'
      //Hide the current page
      oldPage.style.display = 'none'
    }
  </script>
</body>
</html>

The hash mode uses pure static technology to solve the page division of single-page applications. It can switch the URL path without triggering the reloading of the web page. It can be implemented with onhashchange(). Once the hash part of the URL changes, it will be triggered. Function notification, through JavaScript programming, you can quickly realize the switching display of DOM objects. The hash mode also has shortcomings. For example, in a distributed micro front-end project, when both the nested sub-application and the main application use the hash mode, since the URL path of the hash mode can only have one #, it will cause the sub-application and the main application to Applications have difficulties in defining URLs. The URL path in the hash pattern contains #, which will also cause the URL path to be visually unsightly.

Note: Distributed micro front-end: each person on the front-end writes a project, and it is still one project. The web pages need to be deployed on different servers, and users cannot feel it when they visit. If multiple projects cooperate with each other and use hash mode, it will cause # positions to be different, causing problems with project cooperation.

You can change the hash by assigning a value to location.hash

location.hash = '/about'

Pass the a tag and set the href attribute. When the user clicks this tag, the hash value of the URL will change.

<a href="#/hash">Go to hash page</a>

Through the $router.push method, the hash value will be changed to trigger the hashchange event and advance to the specified url.

this.$router.push('/')

The implementation of hash routing mode is mainly based on the following features:

  • The hash value in the URL is only a state of the client, which means that when a request is made to the server, the hash part will not be sent;
  • Changes in the hash value will add a record to the browser’s access history. Therefore, we can control hash switching through the browser’s back and forward buttons;
  • You can pass the a tag and set the href attribute. When the user clicks this tag, the hash value of the URL will change; or use JavaScript to assign loaction.hash to change the hash value of the URL;
  • We can use the hashchange event to listen for changes in the hash value to jump (render) the page.

(2)history mode

The history mode is a commonly used routing mode in VueRouter. It is different from the hash mode. It does not need to use the wrong point technology to rewrite the URL path. Therefore, there is no # in the URL path used by the history mode, which is more visually beautiful and uses H5. Two new APIs pushState() and replaceState() in history and an event onpopstate listen for URL changes. The history mode uses the pushState() function in the history object to rewrite the URL path. The URL path can be changed when reloading is triggered. The principle of the history mode, the code is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>history mode</title>
  <style>
    .page {
      width: 400px;
      height: 400px;
    }
    .about {
      background-color: antiquewhite;
      display: none;
    }
    .index {
      background-color: antiquewhite;
      display: none;
    }
  </style>
</head>
<body>
  <!-- Define routing menu -->
  <!-- Using click events -->
  <a href="javascript:jump('/index')">Jump to index page</a>
  <a href="javascript:jump('/about')">Jump to about page</a>
  <!-- Define page structure -->
  <div class="page index">
    I am the index page
  </div>
  <div class="page about">
    I am about page
  </div>
  <script type="text/javascript">
    //Jump function
    function jump(path){
      history.pushState(null,'page',path)
    // Get all page components
    var pages = document.querySelectorAll('.page')
    // Get the target page object of the specified jump
    var newPage = document.querySelector(path.replace('/','.'))
    //Hide other pages
    pages.forEach(item => item.style.display = 'none')
    // Display the jumped page
    newPage.style.display = 'block'
    }
  </script>
</body>
</html>

The solution for rewriting the URL path in history mode is similar to the hash mode but is essentially different. Although the history mode can rewrite the URL path, the new path after rewriting does not contain the access address of the original HTML physical file, so the history mode After rewriting the URL path, refreshing the web page will cause a 404 inaccessible effect. VueCLI solves the refresh problem of history mode in the development environment. However, when the project is released to the production environment, due to the URL path problem of history mode, it needs to be rewritten with the forwarding rules of the production server to support the routing loading of history mode.

history.pushState() and history.repalceState(). These two APIs can operate the browser’s history without refreshing. The only difference is that the former adds a new history record, while the latter directly replaces the current history record, as shown below:

window.history.pushState(null, null, path); // Add a new history record
window.history.replaceState(null, null, path); // Directly replace the current history record
history.pushState(data, title, targetURL)

parameter:

  • Status object: information passed to the target route, can be empty
  • Page title: Currently not supported by all browsers, just fill in the blank string or null
  • Optional url: target url, does not check whether the url exists, and cannot cross domains. If this item is not passed, data will be added to the current URL.
window.history.replaceState(data, title, targetURL)
  • @Similar to pushState, but it will directly replace the current url without leaving a record in the history

Take this link as an example http://localhost:8080/#/

1. Similarities

None support cross-domain

2. Differences

Whether records will be left

(1)history.pushState

You can use back to indicate that a record has been left.

(2)history.reloaceState

Can’t go back because no record is left.

Note: location.pathname in javascript

Analyze the following URL: http://www.joymood.cn:8080/test.php?user=admin & amp;pwd=admin#login

  • location.href: Get the complete URL as above
  • location.protocol: Get the transport protocol http:
  • location.host: get the host name together with the port www.joymood.cn:8080
  • location.hostname: get the host name www.joymood.cn
  • location.pathname: Get the part after the host that does not include the question mark? /test.php
  • location.search: Get the part after the question mark? and before the pound sign # in the URL ?user=admin & amp;pwd=admin
  • location.hash: get # and the following parts #login

“In the VueCLI project, you can switch the routing’s history mode and hash mode through the mode attribute.

Detailed explanation of how to switch between vue cli2.0 routing hash mode and history mode packaging in vue2 and view local effects – CSDN Blog

Implement switching in vue3

How to switch between hash/history routing modes in vue3_vue3 routing mode-CSDN Blog lianlian