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:
- Check whether the plug-in has been installed. If not, install it.
- Caches global vUE variables to avoid the need for additional import;
- Blend the hook functions beforeCreate and deStory into all Components and register the instance in the hook function.
- Intercepting $router to point to vm. _routerroot. _router;
- Intercept $route to vm. _routerroot. _route;
- Register global components routerView and routerLink.
- 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