下面我会为你详细讲解“vue-router源码之history类的浅析”的完整攻略。
一、什么是 vue-router 的 history 类?
vue-router 提供了多种模式的路由实现,其中一种就是 history 模式。这种模式使用了 HTML5 提供的 History API,可以在不刷新页面的情况下改变浏览器的 URL。 vue-router 的 history 类实现了这种模式的具体逻辑。
二、history 类的基本结构
history 类主要包含了以下几个部分:
- 构造函数
用于初始化 history 实例,同时绑定 popstate 事件的监听器。
- 原型属性
history 实例的原型包含了 navigate、push、replace、go、back、forward 等方法,用于实现改变 URL 的具体逻辑。
- 监听器
history 类为 window 对象绑定了一个 popstate 事件的监听器,当用户通过前进或后退按钮改变 URL 时,会触发该监听器,然后根据不同的情况调用相应的方法。
三、history 类的具体实现
- 构造函数
history 类的构造函数主要做两件事情:
- 绑定 popstate 事件的监听器,该监听器会在浏览器的历史记录栈发生变化时触发,然后根据不同的情况执行不同的操作;
- 初始化 history 实例的各种属性,比如当前页面的路径、状态栈、变化前后的状态等等。
export class History {
...
constructor(router, base) {
this.router = router
this.base = normalizeBase(base)
...
window.addEventListener('popstate', e => {
this.transitionTo(getLocation(this.base), route => {
handlePopState(route)
})
})
...
}
...
}
- navigate 方法
navigate 方法用于实现路由的跳转,它会调用 pushState 或 replaceState 方法改变浏览器的历史记录,并触发 popstate 事件,让监听器根据不同的情况执行不同的操作。
History.prototype.navigate = function (to, replace, fn) {
...
const route = this.router.match(to, this.current)
this.confirmTransition(route, () => {
const prev = this.current
this.updateRoute(route)
fn && fn(route)
this.ensureURL()
this.router.afterHooks.forEach(hook => {
hook && hook(route, prev)
})
if (!this.ready) {
this.ready = true
this.readyCbs.forEach(cb => { cb(route) })
}
})
}
- push 方法
push 方法调用 navigate 方法实现路由的跳转,并将操作类型设置为 push。
History.prototype.push = function (location, onComplete, onAbort) {
this.transitionTo(location, route => {
pushState(cleanPath(this.base + route.fullPath))
onComplete && onComplete(route)
}, onAbort)
}
- replace 方法
replace 方法调用 navigate 方法实现路由的跳转,并将操作类型设置为 replace。
History.prototype.replace = function (location, onComplete, onAbort) {
this.transitionTo(location, route => {
replaceState(cleanPath(this.base + route.fullPath))
onComplete && onComplete(route)
}, onAbort)
}
- ensureURL 方法
ensureURL 方法用于确保浏览器的实际 URL 与 history 实例中存储的 URL 一致。
History.prototype.ensureURL = function (push) {
if (getLocation(this.base) !== this.current.fullPath) {
const current = cleanPath(this.base + this.current.fullPath)
push ? pushState(current) : replaceState(current)
}
}
四、示例说明
下面我们使用两个示例说明 history 类的具体实现。
示例一:使用 push 方法跳转路由
router.push('/home')
调用 push 方法时,会先解析出 /home 对应的路由,然后调用 transitionTo 方法进行路由的切换,最后调用 pushState 方法改变浏览器的历史记录。路由的过渡动画等操作,都是在 transitionTo 方法内实现的。
示例二:通过前进或后退按钮改变 URL
当用户点击前进或后退按钮时,浏览器的历史记录栈会发生变化,此时会触发 popstate 事件,然后调用 history 类的监听器。监听器会根据变化前后的状态,调用 forward 或 back 方法实现路由的切换。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue-router源码之history类的浅析 - Python技术站