Vue-router source code implementation

Introduction to the

Vue-router is the official vueJS route manager. He and vueJS core deep integration.

Use vue-Router:

Steps:

  • Step1: use vue-router plug-in, router.js;
import Router from 'vue-router'
vue.use(Router);
Copy the code
  • Step2: create a vue instance, router.js;
const routes=[  {
       path: '/',
       component: billHome,
       children: [...]
       }
   	{ path: '*',
       hidden: true,
       redirect: { path: '/404' }}];
       
export default new Router({routes});
Copy the code
  • Step3: Add an instance to the root component, main.js;
import router from './router'
new Vue({
	router,
}).$mount('#app');
Copy the code
  • Step4: Add routing view, app.vue;
<router-view></router-view>
Copy the code
  • Step5: add route navigation
<router-link to='/'><router-link>
<router-link to='/test'>test</router-link>
Copy the code

Vue – the router analysis:

  • vue.use(Router); Vue-router is a plug-in that implements the VueRouter class and install method.
  • Two global components need to be implemented:
    • Route view: ‘

      ‘ is used to display component content.
    • Route navigation: ‘

      ‘ is used to navigate forward
  • Listen for URL changes: listen for hashChange or popState events;
  • To respond to the latest URL: Create a responsive property current to record the current route path and display the corresponding component when it changes;

window.location.hash.slice(1);
"/auth-info"

Copy the code

Mapping Routing table

Class vueRouter{constructor(options){// Save options; this.$options=optionos; // Map the routing table during initialization; this.routeMap=new Map(); this.$options.routes.forEach(route=>{ this.routeMap[route.path]=route; }); }}Copy the code

Define the reactive variable current to store path;

Class vueRouter{constructor(options){// Save options; this.$options=optionos; // Map the routing table during initialization; this.routeMap=new Map(); this.$options.routes.forEach(route=>{ this.routeMap[route.path]=route; }); // Create a responsive variable current to save the current route path; Vue.util.defineReactive(this,'current','/'); }}Copy the code

Listen for URL changes; And record the current URL;

Class vueRouter{constructor(options){// Save options; this.$options=optionos; // Map the routing table during initialization; this.routeMap=new Map(); this.$options.routes.forEach(route=>{ this.routeMap[route.path]=route; }); // Create a responsive variable current to save the current route path; Vue.util.defineReactive(this,'current','/'); // listen for URL changes; window.addEventListener('hashchange',this.onHashChange.bind(this)); Window.addeventlistener ('load', this.onhashchange.bind (this))} onHashChange(){// Modify the format of the current URL/hash #/ XXX; this.current=window.location.hash.slice(1); console.log(current); }Copy the code

Mount the VueRouter instance

VueRouter.install=function(_Vue){ Vue=_vue; // mount VueRouter instance; In order to get the router instance in the Vue root instance, global blending is used. Vue. Mixin ({beforeCreate(){// The context is already the component instance; if(this.$options.router){ Vue.prototype.$router=this.$options.router; }}}); }Copy the code

Global registration component router-view router-link

// Register two global components router-view, router-link; // Use the render function to generate the vNode of the corresponding component; Vue.component('router-view',{ render(h){ const {routerMap,current}=this.$router; const component=routerMap[current]? routerMap[current]:null; return h(component); } }) // <router-link to="/">xxx</router-link> Vue.component('router-link',{ props:{ to:{ type:String, default:'' } }, Render (h){// tabName,attrs, data; return h('a',{attrs:{href:'#'+this.to}},this.$slots.default); }});Copy the code

vue-router.js;

// Reference the constructor passed into vue; let Vue ; / / the vue - the router class; new VueRouter({routes:[{},{}]}); Class vueRouter{constructor(options){// Save options; this.$options=optionos; // Map the routing table during initialization; this.routeMap=new Map(); this.$options.routes.forEach(route=>{ this.routeMap[route.path]=route; }); // Create a responsive variable current to save the current route path; Vue.util.defineReactive(this,'current','/'); // listen for URL changes; window.addEventListener('hashchange',this.onHashChange.bind(this)); Window.addeventlistener ('load', this.onhashchange.bind (this))} onHashChange(){// Modify the format of the current URL/hash #/ XXX; this.current=window.location.hash.slice(1); console.log(current); } /** * implement install method; @params Vue constructor; vue.use(VueRouter); The install method passes the vue constructor. */ VueRouter.install=function(_Vue){ Vue=_vue; // mount VueRouter instance; In order to get the router instance in the Vue root instance, global blending is used. Vue. Mixin ({beforeCreate(){// The context is already the component instance; if(this.$options.router){ Vue.prototype.$router=this.$options.router; }}}); // Register two global components router-view, router-link; // Use the render function to generate the vNode of the corresponding component; Vue.component('router-view',{ render(h){ const {routerMap,current}=this.$router; const component=routerMap[current]? routerMap[current]:null; return h(component); } }) // <router-link to="/">xxx</router-link> Vue.component('router-link',{ props:{ to:{ type:String, default:'' } }, Render (h){// tabName,attrs, data; return h('a',{attrs:{href:'#'+this.to}},this.$slots.default); }}); } export default VueRouterCopy the code