preface

Front-end this no route, with more people, there is a front-end route. The concept of routing first appeared in the back end. The emergence of front-end routing starts with Ajax. I won’t go into detail here, but interested partners can learn more about it. Next, let’s understand what front-end routing is and be able to answer these questions succinct and concise in the future.

What is front-end routing?

  • Simply put, the front end controls the page jump, without the need to request the back end
  • In front-end single-page applications, routing describes the mapping between the URL and the UI(page)

Why does front-end routing occur

Before the traditional front-end is a URL for a page, so there is no problem. With the evolution of SINGLE-Page Applications (spAs), component changes and updates no longer correspond to URL changes. However, we need this correspondence (such as direct access to a sub-view of a SPA application via a URL), because the single-page application is not only non-refresh in the page interaction, but also non-refresh in the page hop. In order to implement the single-page application, there is a front-end route. We desperately need a tool to maintain the correspondence between component state and page urls, and that’s where front-end routing comes in.

Pros and cons of single-page applications

Advantages: Good user experience, no need to get everything from the server every time, quickly show the user disadvantages: the forward and back keys of the browser will be used to resend the request, not reasonable use of cache. A single page can’t remember where you scrolled before, and can’t remember where you scrolled forward or backward

How to implement front-end routing

To implement front-end routing, we need to solve two problems:

  1. The page does not refresh when the URL is changed
  2. Detect URL changes and change the page structure

Now that we know what we’re going to do, let’s use this idea to implement two common front-end routing schemes, right

Hash pattern

Implementation principle:

  1. The hash in routing is the # part after the URL.
  2. Add “#” after the page URL, and then splicing other values, address bar return, the page will not jump, here is to change the URL, do not refresh the page.
  3. The next problem is to detect url changes and change the page structure.

We need to know

The change after the “#” in the browser address can be listened to, which gives us the native listener event hashChange. And every time a HashChange event is triggered, you can get the hash value of the current browser address from location.hash

Hashchange events:

When the fragment identifier of the URL changes, the hashChange event is triggered (the part of the URL following the # symbol, including the # symbol). The event object has two properties: the hash URL (oldURL) and the hash URL (newURL) : window.addEventListener(‘hashchange’,function(e) { console.log(e.oldURL); console.log(e.newURL) },false);

With that in mind, let’s implement a simple hash routing:

<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Hash implementation</title>
</head>
<body>
  <div class="page">
    <ul>
      <! -- Two pages -->
      <li>
        <a href="#/home">Home page</a>
      </li>
      <li>
        <a href="#/about">about</a>
      </li>
    </ul>
  </div>
  
  <! -- insert the corresponding URL structure into the DOM structure -->
  <div id="routerView"></div>
  
  <script>
    // Get the Dom structure of the routerView
    let routerView = document.querySelector('#routerView')
    
    // Listen for route changes
    window.addEventListener('hashchange',onHashChange

    // The first time the page is loaded or the first time the page is rendered
    
    // Perform a hash listener when the page is first loaded
    // window.onload = function(){
    // onHashChange()
    // } 
    
    // Listen for the first rendering of the page to complete
    window.addEventListener('DOMContentLoaded',onHashChange)
    
    function onHashChange(){
      // The hashChange event trigger can use location.hash to get the hash value of the current browser address to display different content depending on the path
      console.log(location.hash);
      switch(location.hash){
        case '#/home':
          routerView.innerHTML = 'This is the home page';
          return 
        case '#/about':
          routerView.innerHTML = 'It's about pages';;
          return 
        default:
          return}}</script>
</body>
</html>
Copy the code

If you want to see the effect, you can try it, but it doesn’t refresh. Summary: Since hash changes do not cause page refreshes, hash values are stitched after the URL, and hashChange events are monitored to detect URL changes to display different page (DOM) structures. This is the implementation of hash.

When creating a Vue project and selecting a routing mode, it doesn’t ask you if you want to create a hash mode. Instead, it asks you if you want to use the History mode. From this we can see that the History mode is better than the hash mode. Why is the hash mode inferior to the History mode? The hash mode always puts a # after the URL, while the History mode does not. It is much simpler and does not affect the address bar. Let’s look at the History mode.

The history mode

We first need to understand:

  1. HTML provides a history object that provides the pushState and replaceState methods
  2. You can use popState events to listen for url changes.
  3. You can use history.pushState() and history.replacestate () to replace href events, which change the URL.
  4. PushState () or history.replacestate () do not trigger popState events, so you need to manually trigger page rendering.

MDN read the document to know:

The history.pushState() method adds a state to the history stack of the current browser session, that is, appends a record to the history. history.pushState()

The history.replacestate () method modifies the current history entity. This method is useful if you want to update the current state object or the URL of the current history entity in response to the user’s action. This means you can replace the current page’s information in the history. history.replaceState()

Grammar:

history.pushState(state, title[, url])

history.replaceState(stateObj, title[, url])

With that in mind, let’s implement the History pattern

<! DOCTYPEhtml>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>The history to achieve</title>
</head>
<body>
  <div class="page">
    <ul>
      <! --> < p style = "margin-bottom: 0pt; margin-bottom: 0pt;
      <li><a href="/home">Home page</a></li>
      <li><a href="/about">about</a></li>
    </ul>
    <div id="routerView"></div>
    <script>
      let routerView = document.getElementById('routerView')
      
      // Click the browser's back and forward buttons to change the URL, and listen for popstate to render the correct page
      window.addEventListener('popstate',onPopState)

      // Render the page for the first time
      window.addEventListener('DOMContentLoaded',onLoad)
       
      // Install click events for all a tags
      function onLoad(){
        // The page is initially loaded
        onPopState()
        // Retrieve the corresponding array of a tags with the href attribute
        let linkList = document.querySelectorAll('.page a[href]')
        // Manually assign click events to a tag
        linkList.forEach(el= >{
          el.addEventListener( 'click' , function(e){
          
            // Block the default event for the a tag
            e.preventDefault()  
            
            // Make the URL change manually without refreshing the page
            // getAttribute Gets the href attribute of the current a tag
            history.pushState(null.' ',el.getAttribute('href')) 
            // Manually call onPopState() to detect url changes
            onPopState()
          })
        })
      }
      
      // Detect url changes to display different content
      function onPopState() {
        // location. pathName After the domain name
        switch (location.pathname) {
          case '/home':
            routerView.innerHTML = '< h2 > Home page < / h2 >';
            return
          case '/about': 
            routerView.innerHTML = '< h2 > the About page < / h2 >';
            return
          default:
            return}}</script>
  </div>
</body>
</html>
Copy the code

conclusion

This article provides a brief overview of what front-end routing is and how to simply implement it. Of course, the vue-Router and React-Router implementations are far more complex than these two implementations. Readers will continue to learn the analysis, and I hope this article can help those who need it.