原生JS实现并封装前端路由
目前,前端中所有的MVVM框架中基本都有自己的Router组件,比如React-router或者Vue-router,主要的作用就是通过拦截url来返回相应的组件。如果我们通过原生js来实现一个类似的router,应该怎么做呢?本文将提供一个思路和完整demo,以解释其中的原理。
二.代码示例
服务端(nodejs+express):
const express = require(express); const path = require(path); let app = express(); app.use(/static,express.static(path.join(public))); app.get(/, (req, res) => { res.sendFile(__dirname +/index.html) }) app.get(/router, (req, res) => { res.sendFile(__dirname +/router.html) }) app.listen(2000)
三.代码分析
我先讲讲实现个路由需要从哪几方面入手。
第一步:监听a标签,并给href里的url加锚 我们知道,一般情况下菜单栏的加载模式中,都是通过<a>中的href=/xxxx来跳转到指定的页面,所以路由的第一步就是监听到此菜单栏中<a href=/xxx>的点击事件,并在点击时通过event.preventDefault()阻止浏览器的默认行为。阻止默认行为后,咱们就可以通过#/index这种形式给拿到的url加锚,至于为什么要加锚,第二步中会说明。
第二步:监听hashchange事件,并在监听被触发时加载对应的页面 在第一步中我们给url加上了锚,目的就是通过hashchange函数来监听加了锚之后的url(即hash),监听到hash的变化后,我们可以拿到点击时的url,通过调用Router(params)时传入的params参数来找到此文件的静态路径,然后传入到iframe 的 src中。
注意:在这个例子中我使用的iframe来替代组件,在实际业务情景中,你当然也可以将这个iframe换成一个主容器(<div class="content"></div>之类的),然后在’component’属性中传入组件的具体内容,或者文件路径,都是可以的。
第三步:在Router调用时添加目标容器,添加首页加载 因为我在这个例子中使用的内容容器是个iframe,所以我需要考虑多个iframe嵌套下的Loader目标(target)问题,当然,首页也是需要可以设置默认加载的。 所以,在new Roter()时我们可以看到这两个参数:
四.注意事项
1.这段代码的意义是将函数内this环境绑定到函数内,而不是window。 当然,你也可以这样:
let _this = this;
2.要注意箭头函数中this的指向(箭头函数没有自己的this) 3.如果想把这个demo完整的跑起来,需要安装node环境,然后npm install express。