前言
"理解一个事物最好的方式就是去创造它"
也许有人说重复造轮子没有用,那你可以看看画家们是如何学习的,软件工程内的重复造轮子就相当于绘画中的临摹,通过临摹,我们就可以更好的理解它的原理。好了,话不多说,我们开始今天的主题——手动实现一个简单的SPA应用。
需求
需求是应用的核心,简单说,就是它能完成一件什么事。我们的需求很简单:页面内容要能根据哈希地址的变化而自动更新
功能分析
对需求进行进一步拆分,可以抽象出两个核心功能:记录路由表和根据hash地址匹配路由。
建模
根据上面的功能分析,利用面向对象的编程思维,可以抽象出一个Router对象,代码如下:
class Router {
constructor() {
this.routes = {};// 路由表,记录hash地址和更新行为的对应关系
}
// 添加路由
push(url, callback) {
this.routes[url] = callback;
}
// 匹配路由
route(url) {
this.routes[url] && this.routes[url]();
}
}
组合其他组件,构建应用
单有一个Router对象还不够,我们还需要监听hash地址的变化并触发匹配路由的行为,我们需要BOM相关组件——window对象,整合后的代码如下:
class Router {
constructor() {
this.routes = {};
}
push(url, callback) {
this.routes[url] = callback;
}
route(url) {
this.routes[url] && this.routes[url]();
}
}
const router = new Router();
// 添加一条路由记录
router.push("/home", () => {
console.log("home");
});
// 监听hash地址变化事件
window.addEventListener("hashchange", () => {
const url = window.location.hash.slice(1);
// 根据hash地址匹配路由
app.route(url);
});
测试
新建一个html文件,把js代码放进去,访问文件,最后在地址栏URL最后面输入#/home测试看控制台是否输入回调函数中打印的“home”字符串。
后记
说点题外话,上面的代码中我特意留了个小bug哈哈,相信细心的你,在执行完后一定能发现,发现并调试bug才是软件工程师的真实工作能力,愿你看完本篇文章有所获,早日升职加薪成为想象中的自己!我们一起共勉!