国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

vue-router 源碼實(shí)現(xiàn)前端路由的兩種方式

2019-11-19 13:34:43
字體:
供稿:網(wǎng)友

在學(xué)習(xí) vue-router 的代碼之前,先來簡單了解一下前端路由。

前端路由主要有兩種實(shí)現(xiàn)方法:

  • Hash 路由
  • History 路由

先來看看這兩種方法的實(shí)現(xiàn)原理。

接著我們將用它們來簡單實(shí)現(xiàn)一個(gè)自己的前端路由。

前端路由

Hash 路由

url 的 hash 是以 # 開頭,原本是用來作為錨點(diǎn),從而定位到頁面的特定區(qū)域。當(dāng) hash 改變時(shí),頁面不會(huì)因此刷新,瀏覽器也不會(huì)向服務(wù)器發(fā)送請(qǐng)求。

http://www.xxx.com/#/home

同時(shí), hash 改變時(shí),并會(huì)觸發(fā)相應(yīng)的 hashchange 事件。所以,hash 很適合被用來做前端路由。當(dāng) hash 路由發(fā)生了跳轉(zhuǎn),便會(huì)觸發(fā) hashchange 回調(diào),回調(diào)里可以實(shí)現(xiàn)頁面更新的操作,從而達(dá)到跳轉(zhuǎn)頁面的效果。

window.addEventListener('hashchange', function () { console.log('render');});

History 路由

HTML5 規(guī)范中提供了 history.pushStatehistory.replaceState 來進(jìn)行路由控制。通過這兩個(gè)方法,可以實(shí)現(xiàn)改變 url 且不向服務(wù)器發(fā)送請(qǐng)求。同時(shí)不會(huì)像 hash 有一個(gè) # ,更加的美觀。但是 History 路由需要服務(wù)器的支持,并且需將所有的路由重定向到根頁面。

History 路由的改變不會(huì)去觸發(fā)某個(gè)事件,所以我們需要去考慮如何觸發(fā)路由更新后的回調(diào)。

有以下兩種方式會(huì)改變 url:

  • 調(diào)用 history.pushState 或 history.replaceState;
  • 點(diǎn)擊瀏覽器的前進(jìn)與后退。

第一個(gè)方式可以封裝一個(gè)方法,在調(diào)用 pushState(replaceState)后再調(diào)用回調(diào)。

function push (url) { window.history.pushState({}, null, url); handleHref();}function handleHref () { console.log('render');}

第二個(gè)方式,瀏覽器的前進(jìn)與后退會(huì)觸發(fā) popstate 事件。

window.addEventListener('popstate', handleHref);

路由實(shí)現(xiàn)

我們通過 <a> 標(biāo)簽來進(jìn)行切換路由,通過一個(gè) <div> 標(biāo)簽來裝載各路由對(duì)應(yīng)的頁面內(nèi)容。

參考 vue-router 的調(diào)用,我們會(huì)這么地調(diào)用一個(gè) Router ,將路由與對(duì)應(yīng)組件作為參數(shù)傳入:

const router = new Router([ {  path: '/',  component: 'home' }, {  path: '/book',  component: 'book' }, {  path: '/movie',  component: 'movie' }]);

數(shù)組里是各路由對(duì)應(yīng)的要顯示的內(nèi)容,接下來就來開始實(shí)現(xiàn)這個(gè) Router

Hash 路由實(shí)現(xiàn)

Hash 路由 <a> 標(biāo)簽都需要帶上 #

<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 的代碼實(shí)現(xiàn)如下:

class Router { constructor (options) {  this.routes = {};    this.init();    // 遍歷,綁定視圖更新  options.forEach(item => {   this.route(item.path, () => {   	document.getElementById('content').innerHTML = item.component;   });  }); }  // 綁定監(jiān)聽事件 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](); }  // 將路由與回調(diào)函數(shù)關(guān)聯(lián) route (path, cb) {  this.routes[path] = cb; }}

實(shí)現(xiàn)效果如下:

 

History 路由實(shí)現(xiàn)

History 路由需要服務(wù)器的支持,可以點(diǎn)擊這里 的代碼參考。

<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 的代碼實(shí)現(xiàn)如下:

class Router { constructor (options) {  this.routes = {};  this.init();  this.bindEvent();  // 遍歷,綁定視圖更新  options.forEach(item => {   this.route(item.path, () => {    document.getElementById('content').innerHTML = item.component;   });  }); } // 綁定點(diǎn)擊事件 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);   });  }); } // 綁定監(jiān)聽事件 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](); } // 將路由與回調(diào)函數(shù)關(guān)聯(lián) route (path, cb) {  this.routes[path] = cb; }}

實(shí)現(xiàn)效果如下:

最后

前端路由實(shí)現(xiàn)方式有兩種,分別是:

  1. Hash 路由
  2. History 路由

原理都是修改 url 的同時(shí)不刷新頁面,不向服務(wù)器發(fā)送請(qǐng)求,通過監(jiān)聽特殊的事件來更新頁面。

以上實(shí)現(xiàn)全部源碼參考這里

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 鄂尔多斯市| 蚌埠市| 泾源县| 新宾| 深泽县| 民丰县| 祁东县| 景谷| 桦川县| 莱西市| 禹城市| 潜江市| 大冶市| 会同县| 寻乌县| 镇宁| 庆云县| 扎囊县| 常州市| 仙游县| 泾阳县| 太仆寺旗| 庆元县| 墨玉县| 金堂县| 岱山县| 荥阳市| 儋州市| 安多县| 云南省| 荃湾区| 靖州| 蒲城县| 三亚市| 阜城县| 原阳县| 伊川县| 榆树市| 巨野县| 阳原县| 阳城县|