在学习 vue-router 的代码之前,先来简单了解一下前端路由。
前端路由主要有两种实现方法:
- Hash 路由
- History 路由
先来看看这两种方法的实现原理。
接着我们将用它们来简单实现一个自己的前端路由。
前端路由
Hash 路由
url 的 hash
是以 #
开头,原本是用来作为锚点,从而定位到页面的特定区域。当 hash
改变时,页面不会因此刷新,浏览器也不会向服务器发送请求。
http://www.xxx.com/#/home
同时, hash
改变时,并会触发相应的 hashchange
事件。所以,hash 很适合被用来做前端路由。当 hash 路由发生了跳转,便会触发 hashchange 回调,回调里可以实现页面更新的操作,从而达到跳转页面的效果。
window.addEventListener('hashchange', function () { console.log('render'); });
History 路由
HTML5 规范中提供了 history.pushState
和 history.replaceState
来进行路由控制。通过这两个方法,可以实现改变 url 且不向服务器发送请求。同时不会像 hash
有一个 #
,更加的美观。但是 History 路由需要服务器的支持,并且需将所有的路由重定向到根页面。
History 路由的改变不会去触发某个事件,所以我们需要去考虑如何触发路由更新后的回调。
有以下两种方式会改变 url:
- 调用 history.pushState 或 history.replaceState;
- 点击浏览器的前进与后退。
第一个方式可以封装一个方法,在调用 pushState(replaceState)后再调用回调。
function push (url) { window.history.pushState({}, null, url); handleHref(); } function handleHref () { console.log('render'); }
第二个方式,浏览器的前进与后退会触发 popstate
事件。
window.addEventListener('popstate', handleHref);
路由实现
我们通过 <a>
标签来进行切换路由,通过一个 <div>
标签来装载各路由对应的页面内容。
参考 vue-router 的调用,我们会这么地调用一个 Router
,将路由与对应组件作为参数传入:
const router = new Router([ { path: '/', component: 'home' }, { path: '/book', component: 'book' }, { path: '/movie', component: 'movie' } ]);
数组里是各路由对应的要显示的内容,接下来就来开始实现这个 Router
。
Hash 路由实现
Hash 路由 <a>
标签都需要带上 #
:
<div> <a href="#/" rel="external nofollow" >home</a> <a href="#/book" rel="external nofollow" >book</a> <a href="#/movie" rel="external nofollow" >movie</a> <div id="content"></div> </div>
Router
的代码实现如下:
class Router { constructor (options) { this.routes = {}; this.init(); // 遍历,绑定视图更新 options.forEach(item => { this.route(item.path, () => { document.getElementById('content').innerHTML = item.component; }); }); } // 绑定监听事件 init () { window.addEventListener('load', this.updateView.bind(this), false); window.addEventListener('hashchange', this.updateView.bind(this), false); } // 更新试图 updateView () { const currentUrl = window.location.hash.slice(1) || '/'; this.routes[currentUrl] && this.routes[currentUrl](); } // 将路由与回调函数关联 route (path, cb) { this.routes[path] = cb; } }
实现效果如下:
History 路由实现
History 路由需要服务器的支持,可以点击这里 的代码参考。
<div> <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" data-href="/" rel="external nofollow" >home</a> <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" data-href="/book" rel="external nofollow" >book</a> <a href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" data-href="/movie" rel="external nofollow" >movie</a> <div id="content"></div> </div>
Router
的代码实现如下:
class Router { constructor (options) { this.routes = {}; this.init(); this.bindEvent(); // 遍历,绑定视图更新 options.forEach(item => { this.route(item.path, () => { document.getElementById('content').innerHTML = item.component; }); }); } // 绑定点击事件 bindEvent () { const _this = this; const links = document.getElementsByTagName('a'); [].forEach.call(links, link => { link.addEventListener('click', function () { const url = this.getAttribute('data-href'); _this.push(url); }); }); } // 绑定监听事件 init () { window.addEventListener('load', this.updateView.bind(this), false); window.addEventListener('popstate', this.updateView.bind(this), false); } push (url) { window.history.pushState({}, null, url); this.updateView(); } // 更新试图 updateView () { const currentUrl = window.location.pathname || '/'; this.routes[currentUrl] && this.routes[currentUrl](); } // 将路由与回调函数关联 route (path, cb) { this.routes[path] = cb; } }
实现效果如下:
最后
前端路由实现方式有两种,分别是:
- Hash 路由
- History 路由
原理都是修改 url 的同时不刷新页面,不向服务器发送请求,通过监听特殊的事件来更新页面。
以上实现全部源码参考这里。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- Rachmaninoff-SymphonicDances-BerlinerPhilharmoniker,KirillPetrenko(2024)[24-96]
- 岡部啓一《NieRGestaltReplicantOrchestralArrangementAlbum》24-96\FLAC
- 群星《心光》[FLAC/分轨][307.76MB]
- 许茹芸《讨好》[WAV+CUE][1G]
- 唐磊《丁香花》[WAV+CUE]
- 刘德华.2001-天开了【BMG】【WAV+CUE】
- 群星.2013-顾嘉辉大师经典演唱会3CD【爱我音乐】【WAV+CUE】
- 费翔.2000-费常翔念2CD【环球】【WAV+CUE】
- Rachmaninoff-SuitesNos.12,TheSleepingBeauty-MikuOmine,TakakoTakahashi(2024)[24-
- 童丽《影视金曲(1:1黄金母盘版)》[WAV]
- 柏菲·胭花四乐《胭花四乐》限量开盘母带ORMCD[低速原抓WAV+CUE]
- 群星《监听耳机天碟》2018[WAV分轨][1G]
- 群星《娱协奖原创金曲合辑》滚石[WAV+CUE][1.1G]
- 罗大佑《美丽岛》2CD[WAV+CUE][1.1G]
- 言承旭.2009-多出来的自由【SONY】【WAV+CUE】