'前端開發:vue路由之前端路由的原理'

路由器 瀏覽器 騰訊QQ HTML5 CSS 鵝是程序猿 2019-08-04
"

現在mvvm框架已經火的不成樣了,React、Angular和Vue.js的發佈讓前端工程化成為主流,大前端時代已經到來了,最近接觸了vue的前端路由,閒來無事就開始琢磨源碼,下面來說說前端路由的原理。

一. 前端路由

現代前端開發中最流行的頁面模型,莫過於SPA單頁應用架構。單頁面應用指的是應用只有一個主頁面,通過動態替換DOM內容並同步修改url地址,來模擬多頁應用的效果,切換頁面的功能直接由前臺腳本來完成,而不是由後端渲染完畢後前端只負責顯示。前端三駕馬車Angular,Vue,React均基於此模型來運行的。SPA能夠以模擬多頁面應用的效果,歸功於其前端路由機制。

二. 兩種實現方式

1、hash模式

這裡的hash是指url尾巴後的#號及後面的字符。這裡的#和css裡的#是一個意思。hash也稱作錨點,本身是用來做頁面定位的,她可以使對應id的元素顯示在可是區域內。由於hash值變化不會導致瀏覽器向服務器發出請求,而且hash改變會觸發hashchange事件,瀏覽器的進後退也能對其進行控制,所以人們在 html5 的 history 出現前,基本都是使用 hash 來實現前端路由的。

改變#不觸發網頁加載

http://www.xxxx.com/index.html#location1 
// 改成
http://www.xxxx.com/index.html#location

瀏覽器不會重新向服務器請求index.html

window.location.hash = 'qq' // 設置 url 的 hash,會在當前url後加上 '#qq'
var hash = window.location.hash // '#qq'
window.addEventListener('hashchange', function(){
// 監聽hash變化,點擊瀏覽器的前進後退會觸發
})

下面我來簡單實現一個前端路由的封裝,大家能很清楚的明白vue路由的原理。


<ul>
<li><a href="#/">index</a></li>
<li><a href="#/item">item</a></li>
<li><a href="#/list">list</a></li>
</ul>
<br>
<br>
<div>頭部</div>
<h1 class='result'></h1>
function Router() {
// 路由儲存
this.routes = {};
// 當前路由
this.currentUrl = '';
}
Router.prototype = {
// 路由處理
route: function (path, callback) {
this.routes[path] = callback || function(){};
},
// 頁面刷新
refresh: function () {
// 當前的hash值
this.currentUrl = location.hash.slice(1) || '/';
// 執行hash值改變後相對應的回調函數
this.routes[this.currentUrl]();
},
// 頁面初始化
init: function () {
// 頁面加載事件
window.addEventListener('load', this.refresh.bind(this), false);
// hash 值改變事件
window.addEventListener('hashchange', this.refresh.bind(this), false);
}
}
// 全局掛載
window.Router = new Router();
// 初始化
window.Router.init();
let obj = document.querySelector('.result');
function changeConent (cnt) {
obj.innerHTML = cnt
}
// 匹配路由做相應的操作
Router.route('/', () => {
changeConent("當前是首頁");
})
Router.route('/item', () => {
changeConent('當前是item頁面');
})
Router.route('/list', () => {
// ajax 的數據就可以這樣去拼接
setTimeout(() => {
obj.innerHTML = '<h1 style="color: red">Hello World</h1>'
}, 1000)
})

2、history模式

HTML5規範提供了history.pushState和history.replaceState來進行路由控制。通過這兩個方法可以改變url且不向服務器發送請求。同時不會像hash有一個#,更加的美觀。

下面先看api

window.history.pushState(state, title, url) 
// state:需要保存的數據,這個數據在觸發popstate事件時,可以在event.state裡獲取
// title:標題,基本沒用,一般傳 null
// url:設定新的歷史記錄的 url。新的 url 與當前 url 的 origin 必須是一樣的,否則會拋出錯誤。url可以是絕對路徑,也可以是相對路徑。
//如 當前url是 https://www.baidu.com/a/,執行history.pushState(null, null, './qq/'),則變成 https://www.baidu.com/a/qq/,
//執行history.pushState(null, null, '/qq/'),則變成 https://www.baidu.com/qq/

window.history.replaceState(state, title, url)
// 與 pushState 基本相同,但它是修改當前歷史記錄,而 pushState 是創建新的歷史記錄

window.addEventListener("popstate", function() {
// 監聽瀏覽器前進後退事件,pushState 與 replaceState 方法不會觸發

});

window.history.back() // 後退,觸發popstate事件
window.history.forward() // 前進,觸發popstate事件
window.history.go(1) // 前進一步,-2為後退兩步,window.history.length可以查看當前歷史堆棧中頁面的數量

已經有 hash 模式了,而且 hash 能兼容到IE8, history 只能兼容到 IE10,為什麼還要搞個 history 呢?

首先,hash 本來是拿來做頁面定位的,如果拿來做路由的話,原來的錨點功能就不能用了。其次,hash 的傳參是基於 url 的,如果要傳遞複雜的數據,會有體積的限制,而 history 模式不僅可以在url裡放參數,還可以將數據存放在一個特定的對象中。

hash 和 history API對比

"

現在mvvm框架已經火的不成樣了,React、Angular和Vue.js的發佈讓前端工程化成為主流,大前端時代已經到來了,最近接觸了vue的前端路由,閒來無事就開始琢磨源碼,下面來說說前端路由的原理。

一. 前端路由

現代前端開發中最流行的頁面模型,莫過於SPA單頁應用架構。單頁面應用指的是應用只有一個主頁面,通過動態替換DOM內容並同步修改url地址,來模擬多頁應用的效果,切換頁面的功能直接由前臺腳本來完成,而不是由後端渲染完畢後前端只負責顯示。前端三駕馬車Angular,Vue,React均基於此模型來運行的。SPA能夠以模擬多頁面應用的效果,歸功於其前端路由機制。

二. 兩種實現方式

1、hash模式

這裡的hash是指url尾巴後的#號及後面的字符。這裡的#和css裡的#是一個意思。hash也稱作錨點,本身是用來做頁面定位的,她可以使對應id的元素顯示在可是區域內。由於hash值變化不會導致瀏覽器向服務器發出請求,而且hash改變會觸發hashchange事件,瀏覽器的進後退也能對其進行控制,所以人們在 html5 的 history 出現前,基本都是使用 hash 來實現前端路由的。

改變#不觸發網頁加載

http://www.xxxx.com/index.html#location1 
// 改成
http://www.xxxx.com/index.html#location

瀏覽器不會重新向服務器請求index.html

window.location.hash = 'qq' // 設置 url 的 hash,會在當前url後加上 '#qq'
var hash = window.location.hash // '#qq'
window.addEventListener('hashchange', function(){
// 監聽hash變化,點擊瀏覽器的前進後退會觸發
})

下面我來簡單實現一個前端路由的封裝,大家能很清楚的明白vue路由的原理。


<ul>
<li><a href="#/">index</a></li>
<li><a href="#/item">item</a></li>
<li><a href="#/list">list</a></li>
</ul>
<br>
<br>
<div>頭部</div>
<h1 class='result'></h1>
function Router() {
// 路由儲存
this.routes = {};
// 當前路由
this.currentUrl = '';
}
Router.prototype = {
// 路由處理
route: function (path, callback) {
this.routes[path] = callback || function(){};
},
// 頁面刷新
refresh: function () {
// 當前的hash值
this.currentUrl = location.hash.slice(1) || '/';
// 執行hash值改變後相對應的回調函數
this.routes[this.currentUrl]();
},
// 頁面初始化
init: function () {
// 頁面加載事件
window.addEventListener('load', this.refresh.bind(this), false);
// hash 值改變事件
window.addEventListener('hashchange', this.refresh.bind(this), false);
}
}
// 全局掛載
window.Router = new Router();
// 初始化
window.Router.init();
let obj = document.querySelector('.result');
function changeConent (cnt) {
obj.innerHTML = cnt
}
// 匹配路由做相應的操作
Router.route('/', () => {
changeConent("當前是首頁");
})
Router.route('/item', () => {
changeConent('當前是item頁面');
})
Router.route('/list', () => {
// ajax 的數據就可以這樣去拼接
setTimeout(() => {
obj.innerHTML = '<h1 style="color: red">Hello World</h1>'
}, 1000)
})

2、history模式

HTML5規範提供了history.pushState和history.replaceState來進行路由控制。通過這兩個方法可以改變url且不向服務器發送請求。同時不會像hash有一個#,更加的美觀。

下面先看api

window.history.pushState(state, title, url) 
// state:需要保存的數據,這個數據在觸發popstate事件時,可以在event.state裡獲取
// title:標題,基本沒用,一般傳 null
// url:設定新的歷史記錄的 url。新的 url 與當前 url 的 origin 必須是一樣的,否則會拋出錯誤。url可以是絕對路徑,也可以是相對路徑。
//如 當前url是 https://www.baidu.com/a/,執行history.pushState(null, null, './qq/'),則變成 https://www.baidu.com/a/qq/,
//執行history.pushState(null, null, '/qq/'),則變成 https://www.baidu.com/qq/

window.history.replaceState(state, title, url)
// 與 pushState 基本相同,但它是修改當前歷史記錄,而 pushState 是創建新的歷史記錄

window.addEventListener("popstate", function() {
// 監聽瀏覽器前進後退事件,pushState 與 replaceState 方法不會觸發

});

window.history.back() // 後退,觸發popstate事件
window.history.forward() // 前進,觸發popstate事件
window.history.go(1) // 前進一步,-2為後退兩步,window.history.length可以查看當前歷史堆棧中頁面的數量

已經有 hash 模式了,而且 hash 能兼容到IE8, history 只能兼容到 IE10,為什麼還要搞個 history 呢?

首先,hash 本來是拿來做頁面定位的,如果拿來做路由的話,原來的錨點功能就不能用了。其次,hash 的傳參是基於 url 的,如果要傳遞複雜的數據,會有體積的限制,而 history 模式不僅可以在url裡放參數,還可以將數據存放在一個特定的對象中。

hash 和 history API對比

前端開發:vue路由之前端路由的原理

"

現在mvvm框架已經火的不成樣了,React、Angular和Vue.js的發佈讓前端工程化成為主流,大前端時代已經到來了,最近接觸了vue的前端路由,閒來無事就開始琢磨源碼,下面來說說前端路由的原理。

一. 前端路由

現代前端開發中最流行的頁面模型,莫過於SPA單頁應用架構。單頁面應用指的是應用只有一個主頁面,通過動態替換DOM內容並同步修改url地址,來模擬多頁應用的效果,切換頁面的功能直接由前臺腳本來完成,而不是由後端渲染完畢後前端只負責顯示。前端三駕馬車Angular,Vue,React均基於此模型來運行的。SPA能夠以模擬多頁面應用的效果,歸功於其前端路由機制。

二. 兩種實現方式

1、hash模式

這裡的hash是指url尾巴後的#號及後面的字符。這裡的#和css裡的#是一個意思。hash也稱作錨點,本身是用來做頁面定位的,她可以使對應id的元素顯示在可是區域內。由於hash值變化不會導致瀏覽器向服務器發出請求,而且hash改變會觸發hashchange事件,瀏覽器的進後退也能對其進行控制,所以人們在 html5 的 history 出現前,基本都是使用 hash 來實現前端路由的。

改變#不觸發網頁加載

http://www.xxxx.com/index.html#location1 
// 改成
http://www.xxxx.com/index.html#location

瀏覽器不會重新向服務器請求index.html

window.location.hash = 'qq' // 設置 url 的 hash,會在當前url後加上 '#qq'
var hash = window.location.hash // '#qq'
window.addEventListener('hashchange', function(){
// 監聽hash變化,點擊瀏覽器的前進後退會觸發
})

下面我來簡單實現一個前端路由的封裝,大家能很清楚的明白vue路由的原理。


<ul>
<li><a href="#/">index</a></li>
<li><a href="#/item">item</a></li>
<li><a href="#/list">list</a></li>
</ul>
<br>
<br>
<div>頭部</div>
<h1 class='result'></h1>
function Router() {
// 路由儲存
this.routes = {};
// 當前路由
this.currentUrl = '';
}
Router.prototype = {
// 路由處理
route: function (path, callback) {
this.routes[path] = callback || function(){};
},
// 頁面刷新
refresh: function () {
// 當前的hash值
this.currentUrl = location.hash.slice(1) || '/';
// 執行hash值改變後相對應的回調函數
this.routes[this.currentUrl]();
},
// 頁面初始化
init: function () {
// 頁面加載事件
window.addEventListener('load', this.refresh.bind(this), false);
// hash 值改變事件
window.addEventListener('hashchange', this.refresh.bind(this), false);
}
}
// 全局掛載
window.Router = new Router();
// 初始化
window.Router.init();
let obj = document.querySelector('.result');
function changeConent (cnt) {
obj.innerHTML = cnt
}
// 匹配路由做相應的操作
Router.route('/', () => {
changeConent("當前是首頁");
})
Router.route('/item', () => {
changeConent('當前是item頁面');
})
Router.route('/list', () => {
// ajax 的數據就可以這樣去拼接
setTimeout(() => {
obj.innerHTML = '<h1 style="color: red">Hello World</h1>'
}, 1000)
})

2、history模式

HTML5規範提供了history.pushState和history.replaceState來進行路由控制。通過這兩個方法可以改變url且不向服務器發送請求。同時不會像hash有一個#,更加的美觀。

下面先看api

window.history.pushState(state, title, url) 
// state:需要保存的數據,這個數據在觸發popstate事件時,可以在event.state裡獲取
// title:標題,基本沒用,一般傳 null
// url:設定新的歷史記錄的 url。新的 url 與當前 url 的 origin 必須是一樣的,否則會拋出錯誤。url可以是絕對路徑,也可以是相對路徑。
//如 當前url是 https://www.baidu.com/a/,執行history.pushState(null, null, './qq/'),則變成 https://www.baidu.com/a/qq/,
//執行history.pushState(null, null, '/qq/'),則變成 https://www.baidu.com/qq/

window.history.replaceState(state, title, url)
// 與 pushState 基本相同,但它是修改當前歷史記錄,而 pushState 是創建新的歷史記錄

window.addEventListener("popstate", function() {
// 監聽瀏覽器前進後退事件,pushState 與 replaceState 方法不會觸發

});

window.history.back() // 後退,觸發popstate事件
window.history.forward() // 前進,觸發popstate事件
window.history.go(1) // 前進一步,-2為後退兩步,window.history.length可以查看當前歷史堆棧中頁面的數量

已經有 hash 模式了,而且 hash 能兼容到IE8, history 只能兼容到 IE10,為什麼還要搞個 history 呢?

首先,hash 本來是拿來做頁面定位的,如果拿來做路由的話,原來的錨點功能就不能用了。其次,hash 的傳參是基於 url 的,如果要傳遞複雜的數據,會有體積的限制,而 history 模式不僅可以在url裡放參數,還可以將數據存放在一個特定的對象中。

hash 和 history API對比

前端開發:vue路由之前端路由的原理

前端開發:vue路由之前端路由的原理

"

相關推薦

推薦中...