Implementation principle of Vue router

1, Front end routing concept

By changing the URL, the page view is updated without re requesting the page.

2, Vue router two modes

Updating the view without re requesting the page is one of the cores of the front-end routing principle. At present, there are two main ways to realize this function in the browser environment:

  1. Hash - default value, using hash("#") in URL
  2. history -- use the path in the URL (/ home)

How to set routing mode

const router=new VueRouter({
    mode:'history',
    routes:[...]
})

mode difference:

  1. mode: "hash" is more "#"
http://localhost:8080/#/login
  1. mode:"history"
http://localhost:8080/home

3, HashHistory

hash("#") is used to load the URL indicating the location in the web page# The hash value after the number can be accessed through window location. Hash acquisition

characteristic:

  1. The hash will not be included in the http request and is completely useless to the server. Therefore, changing the hash will not reload the page.
  2. You can add listening events for hash changes: window addEventListener("hashchange",funcRef,false)
  3. Every time you change the hash (window. Localization. Hash), a record will be added to the browser access history.

Using the above characteristics of hash, the function of "updating the view but not requesting the page" of front-end routing can be realized.

HashHistory has two methods: push and replace

Two methods: HashHistory.push() and HashHistory.replace()

HashHistory.push() adds the new route to the top of the stack of browser access history


The process from setting route change to view update:

$router.push() --> HashHistory.push() -->History.transitionTo() --> History.updateRoute() --> {app._route = route} --> vm.render()

Explanation:

$router.push() / / call method
HashHistory.push() / / call according to the hash mode, set the hash and add it to the browser history (add it to the top of the stack) (window.location.hash= XXX)
History.transitionTo() / / monitor the update, and call history updateRoute()
History.updateRoute() / / update route
{app._route= route} / / replace the current app route
vm.render() / / update the view

HashHistory.replace()

The difference between the replace() method and the push() method is that it does not add a new route to the top of the browser access history stack, but replaces the current route

4, HTML5History

In the early History, we can read the information of the browser History stack through methods such as back(), forward(), go()
Starting with HTML5, History provides two new methods: pushState(), replaceState()
Enables us to modify the browser history stack:

window.history.pushState(data, title, targetURL);
@Status object: information transmitted to the target route,Can be empty
@Page Title: currently all browsers do not support,Just fill in the blank string
@Optional url: target url,Will not check url Whether it exists and cannot cross domain. If this item is not transmitted,That is, to the current url add to data
window.history.replaceState(data, title, targetURL);
@be similar to pushState,But it will replace the current one directly url,Instead of history Leave a record in

Assume that the current web address is example com/1. HTML, use the pushState() method to add a new record to the browsing record (History object).

var stateObj = { foo: 'bar' };
history.pushState(stateObj, 'page 2', '2.html');

After adding a new record, the browser address bar immediately displays example com/2.html, but it doesn't jump to 2 HTML, and won't even check 2 Whether HTML exists or not, it just becomes the latest record in browsing history.

The two methods have a common feature: when they are called to modify the browser history stack, although the current url changes, the browser will not immediately send a request for the url, which provides a basis for single page application front-end routing, updating the view but not re requesting the page

More actions:

history.pushState({page: 1}, 'title 1', '?page=1')
// The URL is displayed as http://example.com/example.html?page=1

history.pushState({page: 2}, 'title 2', '?page=2');
// The URL is displayed as http://example.com/example.html?page=2

history.replaceState({page: 3}, 'title 3', '?page=3');
// The URL is displayed as http://example.com/example.html?page=3

history.back()
// The URL is displayed as http://example.com/example.html?page=1

history.back()
// The URL is displayed as http://example.com/example.html

history.go(2)
// The URL is displayed as http://example.com/example.html?page=3

Monitor address change

Listen for popState (window. Onpopustate) in the constructor of HTML5History

After clicking the back and forward buttons (or calling history.back(), history forward(),history. Triggered when the go() method). The premise is that the page Jump cannot really occur, but by history Pushstate() or history Move forward and backward in the history node formed by replacestate()
Note: use history Pushstate() or history Replacestate() does not trigger the popup event.

window.onpopstate = function(event) {
  console.log(event.state);
  console.log(window.history.state;);
};

The above two methods can obtain the data previously passed in pushState and replaceState

Note that the browser will not trigger the pop state event when the page is loaded for the first time.

5, Comparison of two modes

  1. The new URL set by pushState can be any URL with the same origin as the current URL; The hash can only modify # the following parts, so you can only set the URL of the same document as the current one
  2. pushState can add any type of data to the record through stateObject; hash can only add short strings
  3. pushState can additionally set the title property for subsequent use
  4. In the history mode, the URL will be modified to be the same as the URL of the back-end of the normal request. If the back-end does not configure the routing processing corresponding to / user/id, a 404 error will be returned

Auxiliary learning code:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>pushState</title>
    <style type="text/css">
    .hidden {
        display: none;
    }
    </style>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
</head>

<body>
    <section id="step1" class="step-contain" step="1">
        <p>Step 1</p>
        <button class="step-btn" step="1">next step</button>
    </section>
    <section id="step2" class="step-contain hidden" step="2">
        <p>Step 2</p>
        <button class="step-btn" step="2">next step</button>
    </section>
    <section id="step3" class="step-contain hidden" step="3">
        <p>Step 3</p>
    </section>
    <script type="text/javascript">
    $(function() {
        stepProgress();

        function stepProgress() {
            var options = {
                curStep: 1,
                nextStep: null
            }
            var defaultState={
                "step": options.curStep,
                 "url": "#step=" + options.curStep
            }
            window.history.pushState(defaultState, "", defaultState.url);
            $(".step-btn").on("click", function() {
                var step = parseInt($(this).attr("step"));
                options.nextStep = step + 1;
                var state = {
                    "step": options.nextStep,
                    "url": "#step=" + options.nextStep
                }
                window.history.pushState(state, "", state.url);
                console.log(state.step)
                swapStaus(options.nextStep);
            });

            function swapStaus(step) {
                $(".step-contain").each(function() {
                    var tmpStep = $(this).attr("step");
                    if (parseInt(tmpStep) == step) {
                        $("#step" + tmpStep).removeClass("hidden");
                    } else {
                        $("#step" + tmpStep).addClass("hidden");
                    }
                });
                options.curStep = step;
            }

            $(window).on("popstate",function(){
                var currentState = history.state;
                goStep=currentState.step?currentState.step:1;
                swapStaus(goStep)
            })
        }

    })
    </script>
</body>

</html>

Keywords: Front-end Vue.js

Added by yaatra on Mon, 14 Feb 2022 15:43:42 +0200