Handwritten simple Vue router plug-in

A Qiang who wants to fly 2021-09-15 10:51:50

You can think about what you usually use vue-router I went through those steps ?

  • Step one : Use vue-router plug-in unit router.js
 import Router from 'vue-router'
Vue.use(Router)
 Copy code 
  • Step two : establish Router Solid column ,router.js
 export default new Router({...})
 Copy code 
  • Step three : Add a change instance on the component main.js
 import router from './router'
new Vue({
router,
}).mount("#app");
 Copy code 
  • Step four : Add routing view ,App.vue
 <router-view></router-view>
 Copy code 
  • Navigation
 <router-link to='/'>Home</router-link>
<router-link to='/about'>About</router-link>
 Copy code 

Think about the problem :

 Why? Router want use once ? What does it do inside ?
Created router example , Why add it to more components ? What is the purpose ?
<router-view> Why you can use it directly , What is his role ?
<router-link> Why can I use it for navigation ? How is its navigation realized ?
 Copy code 

vue-router Source code implementation

  • In a single page application url When things change , Can't refresh , Display the corresponding view content

Demand analysis

  • spa Page cannot be refreshed
 hash #/about
History api/about
 Copy code 
  • according to url Show the corresponding content
 router-view
Data responsive :current Variable holding url Address , Once changed , Dynamically re execute render
 Copy code 

Mission

  • Implement a plug-in
 Realization VueRouter class
1. Handling routing options
2. monitor url change ,hashChange
3. In response to this change
Realization install Method
1.$router register ( Can be used in any component in the future $router.push() Implement route jump etc. ....)
2. Two global components (router-view router-link)
 Copy code 

Code implementation

  • vue-router.js
/*
vue Plug-in writing
Achieve one install Method
*/
let Vue;
class VueRouter {
constructor(options){
// console.log(Vue);
this.$options = options
// console.log(options);
// Save the current hash To current
// current Must be responsive ,
// Vue.set(this,current,'/') no way ,set The incoming object is required to be a responsive object
// Object.defineProperty() no way ,defineProperty Just intercept , No dependencies established
// Method 1 Give Way vue Do it for us current Responsive work , But it's more complicated
/* new Vue({
data(){
return{
current:'/'
}
}
}) */
// Method 2 vue hide API effect : Define a responsive property for the specified object
Vue.util.defineReactive(this,'current',window.location.hash.slice(1)||'/')
// this.current = '/'
// monitor hashChange
window.addEventListener('hashchange',()=>{
// #/about => /about
this.current = window.location.hash.slice(1)
})
}
}
// Shape parameter 1 yes vue Constructor for install.call(VueRouter,Vue) It is convenient to check the inside of the plug-in Vue Do some deep processing The purpose is : To facilitate extension
VueRouter.install = function (_Vue) {
Vue = _Vue
// 1. take $router Sign up for
// If you register directly, you will not be able to access vue Solid column , because install Method in use When the time comes
// Vue.$router =
// All must be $router Registration is postponed to a future time : Before the real column is created
Vue.mixin({
beforeCreate(){
// You only need to register with the real column once
if (this.$options.router) {
Vue.prototype.$router = this.$options.router
}
}
})
//2. Register two global components ,router-view router-link
Vue.component('router-link',{
props:{
to:String,
require:true
},
// template:"<div>touter-link</div>"
// h Just say createdElement() Function returns a virtual DOM
// <router-link to="/about">asdf</router-link>
// Get slot contents :this.$slots.default
render(h){
// console.log(this.$slots.default);
// console.log(h);
return h('a',{
attrs:{
href:'#'+this.to// The value is not uploaded from the component to The value of the property
}//a The characteristics of the label
},this.$slots.default)
}
})
Vue.component('router-view',{
// template:"<a>touter-view</a>"
render(h){
// Sure · Pass in a component to render directly
// Ideas : According to url Of hash Partially dynamically match the rendered components . So as to realize dynamic rendering
// window.location.hash And routing mapping table (routers) Inside pash Contrast
// console.log(this.$router.$options.routes);
// console.log(this.$router.current);
const router = this.$router.$options.routes.find(router=>router.path===this.$router.current)
let {component} = router
return h(component)
}
})
}
export default VueRouter
 Copy code 
Please bring the original link to reprint ,thank
Similar articles

2021-09-15

2021-09-15