Reference:
  • Learn vue-Router from scratch
  • Interviewer: Do you know anything about front-end routing?
What is vue-router

Vue-router is the link path management system of WebApp. The single-page application of VUE is based on routing and components, which are used to set access paths and map paths to components. The traditional page application uses some hyperlinks to realize the page switch and jump. In vue-Router single-page applications, it is switching between paths, that is, switching between components. The essence of routing module is to establish the mapping between URL and page.

Question: Why not use the A label

Two, vuE-Router implementation principle
1. Vue-router uses the hash mode by default

The HASH of the URL is used to simulate a full URL so that the page does not reload when the URL changes. Hash (#) is the anchor point of the URL, which represents a location in the web page. Simply changing the part after the #, the browser will scroll to that location instead of reloading the web page. This means that the hash appears in the URL, but is not included in the HTTP request. So changing the hash does not reload the page; At the same time, every time the part after # is changed, a record will be added to the browser’s access history. Use the “back” button to go back to the previous position. So Hash mode renders different data for the specified DOM position by changing the anchor value.

Question: How to listen for hash changes — hashchange()

How to simply implement:

  1. withClassKeyword initializes a route.
class Routers {
  constructor() {
    // Store routes as key-value pairs
    this.routes = {};
    // The URL of the current route
    this.currentUrl = ' '; }}Copy the code
  1. Implement hash storage and execution of routes. After initialization we need to think about two questions:

    • Stores the hash of the route and the corresponding callback function
    • After the hash change is triggered, the corresponding callback function is executed
    class Routers {
      constructor() {
        this.routes = {};
        this.currentUrl = ' ';
      }
      // Store the path path and the corresponding callback function
      route(path, callback) {
        this.routes[path] = callback || function() {};
      }
      / / refresh
      refresh() {
        // Get the hash path in the current URL
        this.currentUrl = location.hash.slice(1) | |'/';
        // Execute the callback function for the current hash path
        this.routes[this.currentUrl](); }}Copy the code
  2. Listen for the corresponding event, we only need to listen for the above event when instantiating Class.

class Routers {
  constructor() {
    this.routes = {};
    this.currentUrl = ' ';
    this.refresh = this.refresh.bind(this);
    window.addEventListener('load'.this.refresh, false);
    window.addEventListener('hashchange'.this.refresh, false);
  }

  route(path, callback) {
    this.routes[path] = callback || function() {};
  }

  refresh() {
    this.currentUrl = location.hash.slice(1) | |'/';
    this.routes[this.currentUrl](); }}Copy the code

Full example: Preliminary implementation of hash Router

  1. In addition to implementing rollback functions, hash Router complete code reference
2.vue-routerHistory mode is optional

Since hash mode has a hash tag attached to the URL, if you don’t want an ugly hash, you can use the history mode of the route. Just add “mode: ‘history'” when configuring the routing rule.

/ / the main js file
const router = new VueRouter({
  mode: 'history'.routes: [...]. })Copy the code

This pattern takes advantage of the new pushState() and replaceState() methods in the HTML5 History Interface. These two methods apply to the browser record stack and provide the ability to modify the history in addition to the existing back, Forward, and Go methods. It’s just that when they make changes that change the current URL, the browser doesn’t immediately send requests to the back end. However, this mode to play well, but also need background configuration support. Because our application is a single-page client application, if the background is not properly configured, when the user accesses outsite.com/user/id directly from the browser, it will return 404, which is not pretty. So, you add a candidate resource on the server that covers all cases: if the URL doesn’t match any static resource, it should return the same index.html page that your app relies on.

 export const routes = [ 
  {path: "/".name: "homeLink".component:Home}
  {path: "/register".name: "registerLink".component: Register},
  {path: "/login".name: "loginLink".component: Login},
  {path: "*".redirect: "/"}]
Copy the code
2.1.history APIIntroduction:

There are only a few common ones:

window.history.back();       / / back
window.history.forward();    / / to go forward
window.history.go(- 3);       // Back up three pages
Copy the code

History. pushState is used to add history to the browse history, but does not trigger a jump. This method takes three arguments, in order:

State: a state object associated with the specified url that is passed in a callback function when the POPState event is triggered. If you don't need this object, you can fill it in herenull. Title: The title of the new page, but all browsers currently ignore this value, so it can be filled in herenull. Url: The new url must be in the same domain as the current page. The browser's address bar will display the url.Copy the code

The history.replaceState method takes exactly the same parameters as the pushState method, except that it modifs the current record in the browsing history rather than adding one, and also does not trigger a jump.

Popstate event, which is triggered every time the browsing history (that is, the history object) of the same document changes.

2.2. Implementation of routing under the new standard:
class Routers {
  constructor() {
    this.routes = {};
    this._bindPopState();
  }
  init(path) {
    history.replaceState({path: path}, null, path);
    this.routes[path] && this.routes[path]();
  }

  route(path, callback) {
    this.routes[path] = callback || function() {};
  }

  go(path) {
    history.pushState({path: path}, null, path);
    this.routes[path] && this.routes[path]();
  }
  _bindPopState() {
    window.addEventListener('popstate', e => {
      const path = e.state && e.state.path;
      this.routes[path] && this.routes[path](); }); }}window.Router = new Routers();
Router.init(location.pathname);
const content = document.querySelector('body');
const ul = document.querySelector('ul');
function changeBgColor(color) {
  content.style.backgroundColor = color;
}

Router.route('/'.function() {
  changeBgColor('yellow');
});
Router.route('/blue'.function() {
  changeBgColor('blue');
});
Router.route('/green'.function() {
  changeBgColor('green');
});

ul.addEventListener('click', e => {
  if (e.target.tagName === 'A') {
    e.preventDefault();
    Router.go(e.target.getAttribute('href')); }});Copy the code
3. Use the routing module to realize the way of page skipping
  • Method 1: Modify the address bar directly
  • Method 2: this.$router. Push (‘ router ‘)
  • Method 3:<router-link to=" router address "></router-link>