设计思路
路由跳转最常见的形式是通过 a 标签,当 a 标签被点击的时候,将 a 标签中对应的路径值赋值给 hash。
整个路由的核心连接点是 hash 的值,hash 监听器负责监听 hash 值的变化。
当 hash 值发生改变的时候,去路由表中去查询,将与当前 hash 匹配的 html 页面作为路由出口的内容。
首先看 html 代码
<main id="root">
<header>
<a href="/operation"> 操作系统 </a>
<a href="/network"> 计算机网络 </a>
<a href="/software"> 软件工程 </a>
</header>
<div id="content"></div>
</main>
这里的 content 就是路由出口,当点击不同的 a 标签时,content 内部展示的内容也不同。
其次看 a 标签上绑定的事件
const links = document.querySelectorAll('a');
links.forEach(function (link) {link.addEventListener("click", function (ev) {ev.preventDefault();
const href = this.getAttribute("href");
window.location.hash = href;
});
});
当 a 标签被点击时,禁止 a 标签的默认行为。然后将 a 标签的 href 的值赋给 window.location.hash。
可以看到此时浏览器的地址栏发生更新。
如果到此为止,那么页面不会发生更新,仅仅只是 location 的 hash 的值发生改变。
最后当 hash 发生改变时,页面也该更新。去路由表中查找与 hash 对应的页面,
将这种页面替代原来的路由出口内容。
window.addEventListener("hashchange", function () {const outer = document.querySelector("#content");
const hash = window.location.hash;
const route = routes.find(function (route) {return hash === "#" + route.path;});
outer.innerHTML = route && route.component || "<h1>Error</h1>";
});
完整的代码可以从我的 github 获取完整代码,觉得可以的话,可以点个赞。