首先我们来分析下下面代码
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../view/Home.vue'
// 1.应用插件
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: Home,
},
{
path: '/about',
name: 'about',
component: () =>
import(/* webpackChunkName: "about" */ '../view/About.vue'),
},
]
// 2.创建实例
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
})
export default router
上面是vueRouter一个 常用的配置
- 首先我们要知道vue.use方法会调用传入对象的install方法,并把Vue的构造器传入install方法
接下来我们进入VueRouter的构建
- 首先我们需要创建一个类,并且接收参数,我们将参数都放在$option里
class VueRouter {
constructor(option) {
this.$option = option
this.currentHash = '' // 保存当前url hash
Vue.util.defineReactive(this, 'currentHash', '') // 收集currentHas的依赖,currentHash变化时触发这些依赖
window.addEventLister('hashchange',()=>{ // 监听url hash的变化
this.currentHash = window.location.hash.splice('#')[1]
})
window.addEventLister('load',()=>{ // 获取初始化的url hash
this.currentHash = window.location.hash.splice('#')[1]
})
}
}
2.然后我们创建一个静态方法install来供Vue.use方法调用
class VueRouter {
static install(_vue) { // _vue是Vue的构造函数
// 在这里我们可以 调用Vue原型上的一些方法
Vue.mixin({ // 给组件都注入beforeCreate这个生命周期钩子函数,并将router挂载在原型链$router上
beforeCreate() {
if (this.$options.router) { // 将router示例挂载在原型链$router上
Vue.prototype.$router = this.$options.router
}
}
})
Vue.component('router-link', { // 注册router-link这个全局组件
props: {
to: {
type: String,
require: true,
},
},
render(h) {
return h(
'a',
{ attrs: { href: `#${this.to}` }, class: 'haha' },
this.$slots.default
)
},
})
Vue.component('router-view', { // 注册router-view这个全局组件
render(h) {
let component = null
for (let i = 0; i < this.$router.$option.routes.length; i++) {
if (
this.$router.currentHash ===
this.$router.$option.routes[i].path
) {
component = this.$router.$option.routes[i].component
}
}
return h(component)
},
})
}
}
- 接下来我们实现下push和replace方法
class VueRouter {
push(hash){
history.pushState(hash)
},
replace(hash){
history.replaceState(hash)
}
}
下面是这个代码
class VueRouter {
constructor(option) {
this.$option = option
this.currentHash = '' // 保存当前url hash
Vue.util.defineReactive(this, 'currentHash', '') // 收集currentHas的依赖,currentHash变化时触发这些依赖
window.addEventLister('hashchange',()=>{ // 监听url hash的变化
this.currentHash = window.location.hash.splice('#')[1]
})
window.addEventLister('load',()=>{ // 获取初始化的url hash
this.currentHash = window.location.hash.splice('#')[1]
})
}
static install(_vue) { // _vue是Vue的构造函数
// 在这里我们可以 调用Vue原型上的一些方法
Vue.mixin({ // 给组件都注入beforeCreate这个生命周期钩子函数,并将router挂载在原型链$router上
beforeCreate() {
if (this.$options.router) { // 将router示例挂载在原型链$router上
Vue.prototype.$router = this.$options.router
}
}
})
Vue.component('router-link', { // 注册router-link这个全局组件
props: {
to: {
type: String,
require: true,
},
},
render(h) {
return h(
'a',
{ attrs: { href: `#${this.to}` }, class: 'haha' },
this.$slots.default
)
},
})
Vue.component('router-view', { // 注册router-view这个全局组件
render(h) {
let component = null
for (let i = 0; i < this.$router.$option.routes.length; i++) {
if (
this.$router.currentHash ===
this.$router.$option.routes[i].path
) {
component = this.$router.$option.routes[i].component
}
}
return h(component)
},
})
}
push(hash){
history.pushState(hash)
},
replace(hash){
history.replaceState(hash)
}
}