zhuanlan.zhihu.com/p/337694767

History API

  • The window object provides access to the browser’s session history through the history object;
  • It exposes a number of useful methods and properties that allow you to jump forward and backward through a user’s browsing history;
  1. Use the back(), forward(), and go() methods to jump backwards and forwards through the user’s history
  2. Jump to a point specified in history using the go() method
  3. Window.history. length determines the number of pages in the history stack
  • Starting with HTML5, manipulation of the contents of the history stack is provided.
  1. History.pushstate () adds a history entry
  2. History.replacestate () modifies a history entry
  3. window.onpopstate

Different historical patterns

The history configuration allows us to choose between different history modes when creating the router instance.

Hash pattern

The Hash mode is created with createWebHashHistory()

import { createRouter, createWebHashHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    / /...],})Copy the code

HTML 5 mode

The HTML5 schema is created with createWebHistory

import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    / /...],})Copy the code

The principle of

  • Change url, the page does not refresh
  • When changing the URL, we can listen for changes in the route and do some things (such as updating the DOM)

How to change the URL, the page does not refresh?

  1. HTML5 mode, using replaceState or pushState to change the URL
  2. Browsers do not support replaceState and pushState. Hash mode is used and the URL is replaced with window.location.replace() or window.location.assign()
For example, the current URL is HTTP:/ / 127.0.0.1:9090 / Test# / chartperformwindow.location.replace('#/uploadFile'Change the url to HTTP:/ / 127.0.0.1:9090 / Test# / uploadFilePage not refreshedCopy the code

How do I listen for route changes and trigger DOM updates?

  1. CreateRouter creates the currentRoute object as reactive
    const START_LOCATION_NORMALIZED = {
        path: '/'.name: undefined.params: {},
        query: {},
        hash: ' '.fullPath: '/'.matched: [].meta: {},
        redirectedFrom: undefined};const currentRoute =shallowRef(START_LOCATION_NORMALIZED)
Copy the code
  1. When route navigation is clicked, change the value of currentRoute to trigger view re-rendering
 onClick: link.navigate,
Copy the code
 function navigate(e = {}) {
        if (guardEvent(e))
            return router[unref(props.replace) ? 'replace' : 'push'](unref(props.to));
        return Promise.resolve();
    }
Copy the code
  function push(to) {
        return pushWithRedirect(to);
    }
Copy the code
  function pushWithRedirect(to, redirectedFrom) {
       failure = finalizeNavigation(toLocation, from.true, replace, data);
  }
Copy the code
    function finalizeNavigation(toLocation, from, isPush, replace, data) {
        const error = checkCanceledNavigation(toLocation, from);
        if (error)
            return error;
        const isFirstNavigation = from === START_LOCATION_NORMALIZED;
        conststate = ! isBrowser ? {} : history.state;if (isPush) {
            if (replace || isFirstNavigation)
                routerHistory.replace(toLocation.fullPath, assign({
                    scroll: isFirstNavigation && state && state.scroll,
                }, data));
            else
                routerHistory.push(toLocation.fullPath, data);
        }
        currentRoute.value = toLocation; //currentRoute is modified, triggering the response
        handleScroll(toLocation, from, isPush, isFirstNavigation);
        markAsReady();
    }
Copy the code
  1. The router-view component defines a watch to listen for route changes
        watch(() = > [viewRef.value, matchedRouteRef.value, props.name], ([instance, to, name], [oldInstance, from, oldName]) = > {
            if (to) {
                to.instances[name] = instance;
                if (from && instance === oldInstance) {
                    to.leaveGuards = from.leaveGuards;
                    to.updateGuards = from.updateGuards; }}if (instance &&
                to &&
                (!from| |! isSameRouteRecord(to,from) | |! oldInstance)) { (to.enterCallbacks[name] || []).forEach(callback= >callback(instance)); }}, {flush: 'post' });
Copy the code
  1. Router-view component rendering

The router-view component takes the current route, uses the matcher maintained by the global matcher to match the component corresponding to the current route and renders it.