In the SPA application, when the URL changes, the page is not refreshed and the corresponding view is displayed. Vue Router is the official route manager of Vue. Js
Vue-router Usage procedure
Core steps:
- Step 1: Use the vue-router plug-in, router.js
import Router from 'vue-router'
Vue.use(Router)
Copy the code
- Step 2: Create a Router instance, router.js
export default newRouter({... })Copy the code
- Step 3: Add the instance, main.js, to the root component
import router from './router'
new Vue({
router,
}).$mount("#app");
Copy the code
- Step 4: Add a routing view, app.vue
<router-view></router-view>
Copy the code
- navigation
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
Copy the code
this.$router.push('/')
this.$router.push('/about')
Copy the code
After reading the procedure of vue-Router, we have some questions:
- Vue. What is the use
- Why add a VueRuter instance (Router) to the root component
- Why do we normally use this.$router in components
- Why can we use router-link, router-view directly
By reading the Vue documentation, we can see that vue. Use is the way to use plug-ins
Vue-router is an official plug-in provided by the documentation
Can we know how to develop a plug-in from the vue documentation
With this basic knowledge in hand, we were ready to develop mini-Vue-Router. We need to understand the fundamentals of vue-Router before developing it
Basic principles of vue-Router
Listen for URL changes, match them with the router in the configuration, get the corresponding Component, and render it on the Router-View container Component.
Building infrastructure
- Implement VueRouter class
- Implementing the install method
let Vue // Save the Vue constructor, which can be used in plug-ins without importing
class VueRouter {
constructor (options) {
this.$options = options
}
}
The internal install method is executed when vue.use () is called
VueRouter.install = function (_vue) {
Vue = _vue
}
export default VueRouter
Copy the code
When install is called, it passes in the Vue constructor, mainly so that the standalone plug-in does not need to package Vue in the future. Import Vue from ‘Vue’ packaging will package the entire Vue
Implement router-link, router-view global components
We can use router-link and router-view directly because they are global components
Let’s look at the official description of the global registry component
Router-link, router-view implementation code
VueRouter.install = function(_vue) {
Vue = _vue
Vue.component('router-link', {
props: {
to: {
type: String.require: true}},render(h) {
return h('a', {attrs: {href: The '#' + this.to}}, this.$slots.default)
}
})
Vue.component('router-view', {
render(h) {
// Here is the dynamic rendering
return h()
}
})
}
Copy the code
We used the Render function instead of the template template because the vue package does not come with a compiler by default in a VUe-CLI environment
H is the createElement render function
Deep data object
Router-view dynamic rendering
- Get hash # URL, pass
window.location.hash
To obtain - Get the corresponding component configuration based on the above address (
Component
), and how to get it? h(Component)
Render components by h function- Note:
h
Function can render a component directly
We can use this.$router in any component, but we can also use this.$router in router-view
Registered $router
This instance of VueRouter was injected at the beginning of main.js
The router instance can then use mixins in Install for delayed registration
VueRouter has not been instantiated at the time of install execution, so it should be mixin
Get the hash
Set the current currPath to reactive data with vue.util.definereActive and dynamically re-render if it changes
Display the corresponding content according to the URL
Listen for the address of the hashchange, match it with the router in the configuration, get the corresponding Component, and render it on the router-View container Component
The complete code
let Vue
class VueRouter {
constructor(options) {
this.$options = options
const hashUrl = window.location.hash.slice(1)
Vue.util.defineReactive(this.'currPath', hashUrl || '/')
window.addEventListener('hashchange'.() = > {
this.currPath = window.location.hash.slice(1)
})
}
}
VueRouter.install = function(_vue) {
Vue = _vue
Vue.mixin({
beforeCreate() {
// If it is a root instance, the router instance is available only in $options of the root instance
if (this.$options.router) {
Vue.prototype.$router = this.$options.router
}
},
})
Vue.component('router-link', {
props: {
to: {
type: String.require: true,}},render(h) {
return h('a', { attrs: { href: The '#' + this.to } }, this.$slots.default)
},
})
Vue.component('router-view', {
render(h) {
const route = this.$router.$options.routes.find(
(route) = > route.path === this.$router.currPath
)
const Component = route ? route.component : null
return h(Component)
},
})
}
export default VueRouter
Copy the code