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
- Route view: ‘
- 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