浅析vue-router原理

2020-06-12 21:21:45易采站长站整理

return true
}
// 不是的话,需要手动保证一次 替换 hash 值
replaceHash('/' + path)
return false
}
export function getHash (): string {
// We can't use window.location.hash here because it's not
// consistent across browsers - Firefox will pre-decode it!
// 因为兼容性的问题,这里没有直接使用 window.location.hash
// 因为 Firefox decode hash 值
const href = window.location.href
const index = href.indexOf('#')
return index === -1 ? '' : decodeURI(href.slice(index + 1))
}
// 得到hash之前的url地址
function getUrl (path) {
const href = window.location.href
const i = href.indexOf('#')
const base = i >= 0 ? href.slice(0, i) : href
return `${base}#${path}`
}
// 添加一个hash
function pushHash (path) {
if (supportsPushState) {
pushState(getUrl(path))
} else {
window.location.hash = path
}
}
// 替代hash
function replaceHash (path) {
if (supportsPushState) {
replaceState(getUrl(path))
} else {
window.location.replace(getUrl(path))
}
}

hash的改变会自动添加到浏览器的访问历史记录中。 那么视图的更新是怎么实现的呢,看下 transitionTo()方法:


transitionTo (location: RawLocation, onComplete?: Function, onAbort?: Function) {
const route = this.router.match(location, this.current) //找到匹配路由
this.confirmTransition(route, () => { //确认是否转化
this.updateRoute(route) //更新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) })
}
})
}

//更新路由
updateRoute (route: Route) {
const prev = this.current // 跳转前路由
this.current = route // 装备跳转路由
this.cb && this.cb(route) // 回调函数,这一步很重要,这个回调函数在index文件中注册,会更新被劫持的数据 _router
this.router.afterHooks.forEach(hook => {
hook && hook(route, prev)
})
}
}

pushState
export function pushState (url?: string, replace?: boolean) {
saveScrollPosition()
// try...catch the pushState call to get around Safari
// DOM Exception 18 where it limits to 100 pushState calls
// 加了 try...catch 是因为 Safari 有调用 pushState 100 次限制
// 一旦达到就会抛出 DOM Exception 18 错误
const history = window.history
try {
if (replace) {
// replace 的话 key 还是当前的 key 没必要生成新的