vue-router源码之history类的浅析
当前版本: 3.0.3
类目录: src/history/base.js
前言:
对于vue-router来说,有三种路由模式history,hash,abstract, abstract是运行在没有window的环境下的,这三种模式都是继承于history类,history实现了一些共用的方法,对于一开始看vue-router源码来说,可以从这里开始看起。
初始属性
router: Router; 表示VueRouter实例。实例化History类时的第一个参数 base: string; 表示基路径。会用normalizeBase进行规范化。实例化History类时的第二个参数。 current: Route; 表示当前路由(route)。 pending: ?Route; 描述阻塞状态。 cb: (r: Route) => void; 监听时的回调函数。 ready: boolean; 描述就绪状态。 readyCbs: Array<Function>; 就绪状态的回调数组。 readyErrorCbs: Array<Function>; 就绪时产生错误的回调数组。 errorCbs: Array<Function>; 错误的回调数组 // implemented by sub-classes <!-- 下面几个是需要子类实现的方法,这里就先不说了,之后写其他类实现的时候分析 --> +go: (n: number) => void; +push: (loc: RawLocation) => void; +replace: (loc: RawLocation) => void; +ensureURL: (push?: boolean) => void; +getCurrentLocation: () => string;
对于history类来说,主要是下下面两个函数的逻辑
transitionTo
这个方法主要是对路由跳转的封装, location接收的是HTML5History,HashHistory,AbstractHistory, onComplete是成功的回调,onAbort是失败的回调
transitionTo (location: RawLocation, onComplete?: Function, onAbort?: Function) {
const route = this.router.match(location, this.current) // 解析成每一个location需要的route
this.confirmTransition(route, () => {
this.updateRoute(route)
onComplete && onComplete(route)
this.ensureURL()
// fire ready cbs once
if (!this.ready) {
this.ready = true
this.readyCbs.forEach(cb => { cb(route) })
}
}, err => {
if (onAbort) {
onAbort(err)
}
if (err && !this.ready) {
this.ready = true
this.readyErrorCbs.forEach(cb => { cb(err) })
}
})
}
confirmTransition
这是方法是确认跳转,route是匹配的路由对象, onComplete是匹配成功的回调, 是匹配失败的回调
confirmTransition(route: Route, onComplete: Function, onAbort?: Function) {
const current = this.current
const abort = err => { // 异常处理函数
if (isError(err)) {
if (this.errorCbs.length) {
this.errorCbs.forEach(cb => { cb(err) })
} else {
warn(false, 'uncaught error during route navigation:')
console.error(err)
}
}
onAbort && onAbort(err)
}
if (
isSameRoute(route, current) &&
// in the case the route map has been dynamically appended to
route.matched.length === current.matched.length
) {
this.ensureURL()
return abort()
}
<!-- 根据当前路由对象和匹配的路由:返回更新的路由、激活的路由、停用的路由 -->
const {
updated,
deactivated,
activated
} = resolveQueue(this.current.matched, route.matched)
<!-- 需要执行的任务队列 -->
const queue: Array<?NavigationGuard> = [].concat(
// beforeRouteLeave 钩子函数
extractLeaveGuards(deactivated),
// 全局的beforeHooks勾子
this.router.beforeHooks,
// beforeRouteUpdate 钩子函数调用
extractUpdateHooks(updated),
// config里的勾子
activated.map(m => m.beforeEnter),
// async components
resolveAsyncComponents(activated)
)
this.pending = route
<!-- 对于queue数组所执行的迭代器方法 -->
const iterator = (hook: NavigationGuard, next) => {
if (this.pending !== route) {
return abort()
}
try {
hook(route, current, (to: any) => {
if (to === false || isError(to)) {
// next(false) -> abort navigation, ensure current URL
this.ensureURL(true)
abort(to)
} else if (
typeof to === 'string' ||
(typeof to === 'object' && (
typeof to.path === 'string' ||
typeof to.name === 'string'
))
) {
// next('/') or next({ path: '/' }) -> redirect
abort()
if (typeof to === 'object' && to.replace) {
this.replace(to)
} else {
this.push(to)
}
} else {
// confirm transition and pass on the value
next(to)
}
})
} catch (e) {
abort(e)
}
}
runQueue(queue, iterator, () => {
const postEnterCbs = []
const isValid = () => this.current === route
<!-- beforeRouteEnter 钩子函数调用 -->
const enterGuards = extractEnterGuards(activated, postEnterCbs, isValid)
const queue = enterGuards.concat(this.router.resolveHooks)
<!-- 迭代运行queue -->
runQueue(queue, iterator, () => {
if (this.pending !== route) {
return abort()
}
this.pending = null
onComplete(route)
if (this.router.app) {
this.router.app.$nextTick(() => {
postEnterCbs.forEach(cb => { cb() })
})
}
})
})
}
结语:
每一次总结,都是对之前读源码的再一次深入的了解
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
这篇文章主要介绍了Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定),非常不错,具有参考借鉴价值,感兴趣的朋友一起看看吧2016-11-11
Vue3新特性Suspense和Teleport应用场景分析
本文介绍了Vue2和Vue3中的Suspense用于处理异步请求的加载提示,以及如何在组件间实现动态加载,同时,Teleport技术展示了如何在DOM中灵活地控制组件的渲染位置,解决布局问题,感兴趣的朋友跟随小编一起看看吧2024-07-07
Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验
vee-validate 是为 Vue.js 量身打造的表单校验框架,允许您校验输入的内容并显示对应的错误提示信息。这篇文章给大家带来了Vue.js 使用 Vee-validate 实现表单校验的相关知识,感兴趣的朋友一起看看吧2019-04-04


最新评论