Main knowledge points

  • The Hash and History
  • Routing principle
  • To implement the routing

A VUE routing workflow

  • The front-end routing
    • Input URL –js parsing address — find the address of the corresponding page — perform the page generated JS — see the page
  • The back-end routing
    • Enter the URL – the request is sent to the server – the server parses the path to the request – takes the corresponding page – and returns it
  • The flow chart

Use of Hash and History

  • hash
    • The hash is the content of the hash
    • You can get it from location.hash
    • You can listen for hash changes through onHashchange
  • history
    • History is the normal path
    • location.pathname
    • You can use onPopState to listen for history changes

The source code parsing

The API used when registering the vUE plug-in

import Router from 'vue-router'
Vue.use(Router)
Copy the code

Ultimately, the install method of the plug-in is executed

install

The method mainly does the following things:

  1. Check whether the plug-in has been installed. If not, install it.
  2. Caches global vUE variables to avoid the need for additional import;
  3. Blend the hook functions beforeCreate and deStory into all Components and register the instance in the hook function.
  4. Intercepting $router to point to vm. _routerroot. _router;
  5. Intercept $route to vm. _routerroot. _route;
  6. Register global components routerView and routerLink.
  7. The route hook function uses the same merge strategy as the component hook function created.

Implement a basic VUe-Router

  • The main points of
    • Installl :function(Vue);
    • To mix Vue instances globally, use Vue. Mixin;
    • Use of Vue. Util. defineReactive, which is the method used to listen on data in Vue. This method can be used to monitor current changes;
class HistoryRouter { constructor() { this.current = null; } } class VueRouter { constructor(options) { this.mode = options.mode || 'hash'; this.routes = options.routes || []; this.history = new HistoryRouter(); this.routesMap = this.createMap(this.routes); this.init(); } init() { this.listenUrlChange(this.mode); } listenUrlChange(mode) { location.hash ? "" : location.hash = '/'; window.addEventListener('load', () => { this.history.current = location.hash.slice(1); }); var eventName = mode === 'hash' ? 'hashchange' : 'popstate'; window.addEventListener(eventName, () => { this.history.current = location.hash.slice(1); }); } createMap(routes) { return routes.reduce((memo, current) => { memo[current.path] = memo[current.component]; return memo; }, {}); } } VueRouter.install = function(Vue) { Vue.mixin({ beforeCreate() { if (this.$options && this.$options.router) { this._root = this; this._router = this.$options.router; Vue.util.defineReactive(this, 'currrent', this._router.history); } else { if (this.$parent) { this._root = this.$parent._root; } } Object.defineProperty(this, '$router', { get() { return this._root._router; } // do not write set, because external can not modify this.$router value}); }}); Vue.component('router-view', {render(h) {let current = this._self._root._router.history.current; let routesMap = this._self._root._router.routesMap; let component = routesMap[current]; // Get the component and render the component h(component); }}); } export default VueRouter;Copy the code