前端路由实现的关键知识点
一、如何拿到页面的url?
- 采用location.hash+window.hashchange事件
1.不管是直接在链接标签上指定hash(<a href='#abc'>test</test>)还是通过location.hash='#1234'设置hash都会导致浏览器地址栏变化,从而触发hashchange事件
2.hashchange事件中可通过event.newURL来获取改变后的页面地址,然后从该url中提取#后面的内容(一般是一个页面地址及参数)
- 通过history.pushState和window.popstate事件
1.通过window.history.pushState/replaceState(数据对象,标题,url)可生成一条历史记录,该方法会导致浏览器地址栏变更,但页面不会发生跳转
2.点击浏览器的前进、后退,或者location.hash发生变更时会触发window.popstate事件,在事件中可通过event.state获取第一步设置的数据对象
3.通过pushState/replaceState或<a>
标签改变 URL时 不会触发 popstate 事件。好在我们可以拦截 pushState/replaceState的调用和<a>
标签的点击事件来检测 URL 变化
window.history.pushState = new Proxy(window.history.pushState, { apply(target, thisBinding, args) { //下个页面的地址 const nextPathName = args[2]; /* 执行自定义逻辑 ... */ // 继续执行原有的程序 return target.apply(thisBinding, args); } });
二. 如何让url匹配到相应的组件?
以一个最基本的react-router组件进行分析:
<Router history={hashHistory}> <Route path="/" component={App}/> <Route path="/repos" component={Repos}/> <Route path="/about" component={About}/> </Router>
第一步拿到页面的url后,再遍历Router子组件,取出Route.path用path-url-regexp跟页面url匹配,如果匹配,则渲染component属性指定的组件