手写VueRouter
Posted michael_yqs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手写VueRouter相关的知识,希望对你有一定的参考价值。
定义VueRouter类
export default class VueRouter {
//构造函数中把参数存储下来
constructor(options) {
this.options = options
this.routeMap = {}//用于存储路由对应的view组件
const cur =
(this.options.mode === 'history'
? location.pathname
: location.href.split('#')[1]) || '/'/*当前路由
若是history模式,则直接取pathname,否则解析出#后面的内容作为路由*/
this.data = _Vue.observable({
current: cur,
})
}
实现静态方法install
在里面需要判断插件是否安装,安装了则什么也不做,否则注入实例
static install(vue) {
//判断当前插件是否已安装
if (VueRouter.install.isinstalled) {
return
}
VueRouter.install.isinstalled = true
//把vue构造函数记录到全局变量
_Vue = vue
//把创建vue实例时传入的router对象注入到vue实例上
_Vue.mixin({
beforeCreate() {
if (this.$options.router) {
_Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
},
})
}
init() {
this.createRouteMap()//建立路由和view的映射关系
this.initComponents(_Vue)//component渲染
this.initEvent()//浏览器事件处理
}
存储路由对应的组件
//解析路由规则为键值对形式,存储到实例的routemap 中
createRouteMap() {
this.options.routes.forEach((route) => {
this.routeMap[route.path] = route.component
})
}
处理router-link,router-view
initComponents(Vue) {
let self = this
Vue.component('router-link', {
props: {
to: String,
},
render(h) {
return h(
'a',
{
attrs: {
href: this.to,
},
on: {
click: this.handleClick,//绑定事件
},
},
[this.$slots.default],
)
},
methods: {
handleClick(e) {
if (self.options.mode === 'history') {
history.pushState({}, '', this.to)
this.$router.data.current = this.to
} else {
location.hash = this.to
this.$router.data.current = this.to.split('#')[1]
}
e.preventDefault()
},
},
//template: '<a :href="to"><slot></slot></a>',
})
Vue.component('router-view', {
render(h) {
let component = self.routeMap[self.data.current]
return h(component)
},
})
}
浏览器前进后退事件处理
根据不同模式监听不同的浏览器事件
//注册事件
initEvent() {
//history模式
if (this.options.mode === 'history') {
window.addEventListener('popstate', () => {
this.data.current = location.pathname
})
} else {
//hash模式
window.addEventListener('hashchange', () => {
this.data.current = location.hash.substring(1)
})
}
}
以上是关于手写VueRouter的主要内容,如果未能解决你的问题,请参考以下文章