Vue Router的核心功能是实现前端路由,即在不重新加载页面的情况下更改应用的视图。它的基本架构包括:
Vue Router支持两种主要的路由模式:Hash模式和History模式。
Hash模式利用URL的hash部分(#
后面的部分)来模拟完整的URL。其核心实现原理:
// 简化的Hash模式实现
class HashRouter {
constructor() {
// 监听hashchange事件
window.addEventListener('hashchange', () => {
this.onHashChange();
});
}
onHashChange() {
const hash = window.location.hash.slice(1);
// 根据hash值渲染对应组件
this.renderComponent(hash);
}
push(path) {
window.location.hash = path;
}
}
Hash模式的优点是兼容性好,即使在IE9这样的老浏览器中也能正常工作,因为它不需要服务器配置。
History模式利用HTML5 History API来实现URL的变化而无需刷新页面:
// 简化的History模式实现
class HistoryRouter {
constructor() {
// 监听popstate事件
window.addEventListener('popstate', () => {
this.onPopState();
});
}
onPopState() {
const path = window.location.pathname;
// 根据path渲染对应组件
this.renderComponent(path);
}
push(path) {
// 使用History API更改URL
history.pushState({}, '', path);
this.renderComponent(path);
}
}
History模式需要服务器配置,确保用户直接访问任何路由时都返回index.html,否则会出现404错误。
Vue Router使用路径-组件映射表来确定应该渲染哪个组件。其匹配算法支持:
/user/:id
)路由匹配的核心是将URL路径解析为路由记录,然后找到对应的组件进行渲染:
// 简化的路由匹配实现
function matchRoute(routes, path) {
for (const route of routes) {
// 处理动态参数路由
const regex = pathToRegexp(route.path);
const match = regex.exec(path);
if (match) {
// 提取参数
const params = extractParams(route.path, match);
return {
component: route.component,
params
};
}
}
return null; // 没有匹配的路由
}
Vue Router的路由守卫是其强大功能之一,允许控制导航过程。主要包括:
router.beforeEach
、router.afterEach
beforeEnter
beforeRouteEnter
、beforeRouteUpdate
、beforeRouteLeave
路由守卫的实现本质上是一个中间件系统,通过Promise链式调用实现异步控制流:
// 简化的路由守卫实现
function runGuards(guards, to, from, next) {
let index = 0;
function proceed() {
// 所有守卫都执行完毕
if (index >= guards.length) {
next();
return;
}
const guard = guards[index++];
// 执行当前守卫
guard(to, from, (result) => {
if (result === false) {
// 取消导航
next(false);
} else if (typeof result === 'object') {
// 重定向
next(result);
} else {
// 继续执行下一个守卫
proceed();
}
});
}
proceed();
}
Vue Router支持路由懒加载,即按需加载路由组件,提高应用性能。其实现原理是结合Webpack的代码分割功能:
// 路由懒加载示例
const routes = [
{
path: '/about',
component: () => import('./views/About.vue')
}
];
当用户访问/about
路径时,才会加载About组件。这是通过动态import()函数实现的,它返回一个Promise,Vue Router会等待Promise解析后再渲染组件。
Vue Router与Vue的响应式系统深度集成。当路由变化时,Vue Router会更新一个响应式的currentRoute
对象,任何依赖这个对象的组件都会自动重新渲染:
// 简化的响应式实现
class Router {
constructor(Vue) {
// 创建响应式的当前路由对象
this.currentRoute = Vue.observable({
path: '/',
params: {},
query: {}
});
}
updateRoute(route) {
// 更新响应式对象,触发视图更新
Object.assign(this.currentRoute, route);
}
}
Vue Router的核心实现原理包括: