手写Vue Router 路由简单原理
Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单⻚面应用变得易如反掌。
核心步骤:
步骤一:使用vue-router插件,router.js
import Router from 'vue-router' Vue.use(Router)
步骤二:创建Router实例,router.js
export default new Router({...})
步骤三:在根组件上添加该实例,main.js
import router from './router'
new Vue({
router,
}).$mount("#app");
步骤四:添加路由视图,App.vue
<router-view></router-view>
导航
<router-link to="/">Home</router-link> <router-link to="/about">About</router-link>
vue-router源码实现
需求分析
-
-
实现两个全局组件:router-view用于显示匹配组件内容,router-link用于跳转
-
监控url变化:监听hashchange或popstate事件
-
源码:
/* 路由器插件 */
/* Vue.use(VRouter) */
let Vue
class VRouter {
constructor(options) {
this.$options = options
// 缓存path和route映射关系
this.routeMap = {}
this.$options.routes.forEach(
route => {
this.routeMap[route.path] = route
})
// 响应式数据,响应式数据依赖于vue
// current保存当前url
// defineReactive给obj定义一个响应式属性 #/about
const initial = window.location.hash.slice(1)
Vue.util.defineReactive(this, 'current', initial) // this指向为router实例
// 3.监控url变化
window.addEventListener('hashchange', this.onHashChange.bind(this))
}
onHashChange () {
this.current = window.location.hash.slice(1)
}
}
// 1.实现install方法,注册$router和两个路由全局组件
VRouter.install = function (_Vue) {
// 引用构造函数,VRouter中要使用
Vue = _Vue
// 挂载router实例,让我们的子组件可以使用它
// 为了解决install先执行,还要在这里访问router实例(此时还未生成router实例)
// 做一个全局混入,在beforCreate钩子里面做这件事
Vue.mixin({
beforeCreate () {
// 此时上下文已经是组件实例
// 如果this是根实例,则它的$options里面会有路由实例
if(this.$options.router) {
Vue.prototype.$router = this.$options.router
}
}
})
// 2.实现两个全局组件: router-link , router-view
// 输入:<router-link to="/about">xxx</router-link>
// 输出:<a href="#/about">xxx</a>
Vue.component('router-link', {
props: {
to: {
type: String,
required: true
}
},
render(h) {
return h('a', {
attrs: {
href: '#' + this.to
}
},
[this.$slots.default])
}
})
Vue.component('router-view', {
render(h) {
// 找到当前url对应组件
const { current, routeMap } = this.$router
const component = routeMap[current] ? routeMap[current].component : null
// 渲染传入组件
return h(component)
}
})
}
export default VRouter

浙公网安备 33010602011771号