前言
vue-router是vue的官方路由库,它提供了两种路由模式history和hash。分别有着不同的实现原理,并且在3版本和4版本对hash模式的实现也是不同的。
一、history模式实现原理
vue-router3.0版本和4.0版本下history模式的实现原理都是通过封装window.history对象来实现。
大致流程就是
封装history
vue-router通过封装history的方法(pushState、replaceSatte)等方法,使的我们在调用vue-router上方法(push等)时能够做到两件事。- 使得命中的路由组件渲染或销毁
- 同步浏览器的页面栈数据,当页面重新刷新或者点击前进后退按钮的时候,能够渲染正确的组件
监听popstate事件
popstate事件只会在浏览器前进后退时触发,即调用history的(go、back、forward)方法。通过监听这个事件,实现浏览器按钮点击前进、退后时,页面渲染结果与页面路劲的同步
从严格意义上来说vue项目是只有一个index.html页面的,所有的页面的切换效果,只是vue-router通过切换组件模拟出来的。
源码代码实现
监听popstate
// set up the listeners and prepare teardown callbacks
window.addEventListener('popstate', popStateHandler);
// TODO: could we use 'pagehide' or 'visibilitychange' instead?
// https://developer.chrome.com/blog/page-lifecycle-api/
window.addEventListener('beforeunload', beforeUnloadListener, {
passive: true,
});
封装history对应方法
function push(to) {
return pushWithRedirect(to);
}
function replace(to) {
return push(assign(locationAsObject(to), { replace: true }));
}
二、hash模式实现原理
hash模式和history模式处理流程是一致的,只不过监听的事件和对url的处理逻辑不一样。
hash模式在3.0版本中,通过监听hashchange事件来实现hash改变后页面渲染与hash同步。
const eventType = supportsPushState ? 'popstate' : 'hashchange'
window.addEventListener(
eventType,
handleRoutingEvent
)
在4.0版本中,就不再监听hashchange事件了。通过对history.pushState或replaceState中url参数加#/,就能实现既改变了window.history对象也改变window.hash对象。把页面的路由信息存储起来
const hashIndex = base.indexOf("#");
const url =
hashIndex > -1
? (location.host && document.querySelector("base")
? base
: base.slice(hashIndex)) + to
: createBaseLocation() + base + to;
try {
// BROWSER QUIRK
// NOTE: Safari throws a SecurityError when calling this function 100 times in 30 seconds
history[replace ? "replaceState" : "pushState"](state, "", url);
historyState.value = state;
} catch (err) {
if (process.env.NODE_ENV !== "production") {
warn("Error with push/replace State", err);
} else {
console.error(err);
}
// Force the navigation, this also resets the call count
location[replace ? "replace" : "assign"](url);
}
所以当浏览器前进\后退的时候,因为监听了popstate事件,所以同样能在事件处理函数中处理url改变带来的页面改变
// set up the listeners and prepare teardown callbacks
window.addEventListener("popstate", popStateHandler);
// TODO: could we use 'pagehide' or 'visibilitychange' instead?
// https://developer.chrome.com/blog/page-lifecycle-api/
window.addEventListener("beforeunload", beforeUnloadListener, {
本文详细解析了VueRouter3.0和4.0中history和hash模式的实现原理,包括如何通过封装window.history对象和监听popstate/hashchange事件来控制页面渲染。着重介绍了在不同版本中如何处理浏览器前进后退操作保持页面同步。
9414

被折叠的 条评论
为什么被折叠?



