国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

從history api看主流框架的路由機制

Lyux / 3299人閱讀

摘要:前端路由庫的作用是改變地址欄,支持瀏覽器前進后退,并同步路由對應(yīng)的視圖,這里以及其依賴的庫說一下路由機制原文地址前提首先簡單介紹一下前端路由機制所依賴的事件及對應(yīng)的事件對于支持新增方法的瀏覽器,可以通過設(shè)置來在瀏覽器棧中新增一條記錄設(shè)置時

前端路由庫的作用是改變地址欄,支持瀏覽器前進、后退,并同步路由對應(yīng)的視圖,這里以react-router及其依賴的history庫說一下路由機制

原文地址

前提

首先簡單介紹一下前端路由機制所依賴的pushState、popstate事件、hash及對應(yīng)的hashChange事件

pushState,popstate

對于支持html5 新增pushState、replaceState方法的瀏覽器,可以通過設(shè)置pushState來在瀏覽器history棧中新增一條記錄

設(shè)置pushState(),replaceState()時并不會觸發(fā)popstate事件,popstate事件只在點擊瀏覽器前進、后退按鈕或調(diào)用history.back()、history.forward()等時觸發(fā)

pushState()方法第一個參數(shù)可以指定一個state對象,并通過history.state或popstate事件回調(diào)中event對象獲取

history.pushState(state,title,path)

console.log(history.state)

window.addEventListener("popstate",(e)=>{

    console.log(e.state)

})

location.hash hashChange

對于不支持pushState方法的瀏覽器,可以通過改變location.hash和借助hashChange事件來實現(xiàn)路由功能

window.addEventListener("hashchange",e=>{

})

location.hash="test"

對比

通過設(shè)置history.pushState(state,title,path),可以給對應(yīng)路由設(shè)置一個state,這就給路由之間的數(shù)據(jù)傳遞提供了一種新途徑,并且,state對象是保存在本地的,刷新頁面依然存在,但通過hash方式實現(xiàn)的路由就沒法使用,react-router v4版本也去除了對state的模擬

history庫介紹

history庫提供了三種不同的方法來創(chuàng)建history對象,這里的history對象是對瀏覽器內(nèi)置window.history方法的擴展,擴展了push,go,goBack,goForward等方法,并加入了location、listen字段,并對非瀏覽器環(huán)境實現(xiàn)polyfill

createBrowserHistory()
createHashHistory()
createMemoryHistory()
react-router的路由實現(xiàn)(BrowserRouter和createBrowserHistory)

react-router路由實現(xiàn)大體過程

調(diào)用history.push跳轉(zhuǎn)路由時,內(nèi)部執(zhí)行window.history.pushState在瀏覽器history棧中新增一條記錄,改變url,執(zhí)行組件注冊的回調(diào)函數(shù),

createBrowserHistory中注冊popstate事件,用戶點擊瀏覽器前進、回退時,在popstate事件中獲取當(dāng)前的event.state,重新組裝一個location,執(zhí)行組件注冊的回調(diào)函數(shù)

history庫對外暴露createBrowserHistory方法,react-router中實例化createBrowserHistory方法對象,在組件中注冊history.listen()回調(diào)函數(shù),當(dāng)路由有變化時,組件中匹配location,同步UI

分別來看

history.push

在react中,我們可以調(diào)用history.push(path,state)來跳轉(zhuǎn)路由,實際執(zhí)行的就是createBrowserHistory中的push方法

在這個方法中主要做三件事

根據(jù)傳遞的path,state參數(shù)創(chuàng)建一個location,不同于window.location,這里的location只有這些屬性

   location= {
      path:
      search:
      hash:
      state:
      key
    };
    const location = createLocation(path, state, createKey(), history.location);

這個location會在組件中使用,來根據(jù)location中的值和中的path匹配,匹配成功的Route組件渲染指定的component

執(zhí)行g(shù)lobalHistory.pushState({ key, state }, null, href);

執(zhí)行Router中注冊的listener

const action = "PUSH"
setState({ action, location });

const setState = nextState => {
    Object.assign(history, nextState);

    history.length = globalHistory.length;

    transitionManager.notifyListeners(history.location, history.action);
};
history中對popstate事件的注冊

popstate事件觸發(fā)時,可以得到event.state,createBrowserHistory中會根據(jù)這個state和當(dāng)前window.location重新生成一個location對象,執(zhí)行Router組件注冊的listener,同步UI

const setState = nextState => {
    Object.assign(history, nextState);

    history.length = globalHistory.length;

    transitionManager.notifyListeners(history.location, history.action);
  };

const handlePop = location => {
    const action = "POP";
    setState({action,location)
}
組件

BrowserRouter組件中會實例化一個createBrowserHistory對象,傳遞給Router組件

class BrowserRouter extends React.Component{

    history = createHistory(this.props);

    render() {
        return ;
    }

}

在Router組件中要注冊history.listen()的一個監(jiān)聽函數(shù),并且保存一份子組件(Route)使用的數(shù)據(jù)

getChildContext() {
    return {
      router: {
        ...this.context.router,
        history: this.props.history,
        route: {
          location: this.props.history.location, //history中的location
          match: this.state.match
        }
      }
    };
  }
componentWillMount{
    this.unlisten = history.listen(() => {
        this.setState({
            match: this.computeMatch(history.location.pathname)
        });
    });
}

當(dāng)調(diào)用history.push或觸發(fā)popstate事件時,這里注冊的listener都會被createBrowserHistory執(zhí)行,觸發(fā)setState,然后Router的子組件中匹配的會重新渲染,





在Route中有一個match狀態(tài),在父組件props發(fā)生變化時會重新計算

state = {
    match: this.computeMatch(this.props, this.context.router)
  };

componentWillReceiveProps(nextProps, nextContext) {
    this.setState({
      match: this.computeMatch(nextProps, nextContext.router)
    });
}
//computeMatch主要工作就是匹配當(dāng)前組件上指定的path和當(dāng)前瀏覽器的路徑是否一致,一致就渲染組件

render() {

    if (component) return match ? React.createElement(component, props) : null;

    if (render) return match ? render(props) : null;

}
總結(jié)

總結(jié)一下,react-router的路由機制就是

借助history庫,history中實現(xiàn)了push,go,goBack等方法,注冊了popstate事件,當(dāng)路由跳轉(zhuǎn)時,使用瀏覽器內(nèi)置的history api 操作 history棧

history庫對外暴露的history對象提供了listen方法,組件會注冊一個listener

當(dāng)調(diào)用hsitory.push或popstate事件觸發(fā)時,執(zhí)行l(wèi)istener

注冊的監(jiān)聽函數(shù)內(nèi)部會setState更新狀態(tài)

的子組件的componentWillReceiveProps生命周期函數(shù)中能得到Router中context,根據(jù)當(dāng)前path和瀏覽器當(dāng)前l(fā)ocation來判斷當(dāng)前route是否match,匹配就渲染component

雖然本文以react-router來介紹路由機制,但主流路由庫實現(xiàn)原理都差不多,借助pushState或hash來更新url,在對應(yīng)的事件處理函數(shù)中來做視圖的同步

參考

createBrowserHistory.js

locationUtil.js

BrowserRouter.js

Router.js

Route.js

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/107215.html

相關(guān)文章

  • 前端路由實現(xiàn)與 react-router 源碼分析

    摘要:回調(diào)函數(shù)將在更新時觸發(fā),回調(diào)中的起到了新的的作用。注冊回調(diào)在中使用注冊的回調(diào)函數(shù),最終放在模塊的回調(diào)函數(shù)數(shù)組中。 原文地址:https://github.com/joeyguo/blog/issues/2 在單頁應(yīng)用上,前端路由并不陌生。很多前端框架也會有獨立開發(fā)或推薦配套使用的路由系統(tǒng)。那么,當(dāng)我們在談前端路由的時候,還可以談些什么?本文將簡要分析并實現(xiàn)一個的前端路由,并對 reac...

    ISherry 評論0 收藏0
  • 讓前端監(jiān)控數(shù)據(jù)采集更高效

    摘要:如何在新的技術(shù)背景下讓前端數(shù)據(jù)采集工作更加完善高效,是本文討論的重點。具體來說,我們對前端的數(shù)據(jù)采集具體主要分為路由切換性能資源錯誤日志上報路由切換等前端技術(shù)的快速發(fā)展使單頁面應(yīng)用盛行。 隨著業(yè)務(wù)的快速發(fā)展,我們對生產(chǎn)環(huán)境下的問題感知能力越來越關(guān)注。作為距離用戶最近的一層,前端的表現(xiàn)是否可靠、穩(wěn)定、好用,很大程度上決定著用戶對整個產(chǎn)品的體驗和感受。因此,對于前端的監(jiān)控不容忽視。 搭建一...

    Half 評論0 收藏0
  • SPA那點事

    摘要:單頁面應(yīng)用的出現(xiàn)依然存在著爭議性,我們該如何看待他的兩面性呢接下來小生給大家總結(jié)一下他的優(yōu)缺點。單頁面應(yīng)用的優(yōu)勢無刷新體驗沒有了令人詬病的頁面頻繁刷新,同時節(jié)約瀏覽器資源,路由響應(yīng)比較及時,提升了用戶的體驗。 前端猿一天不學(xué)習(xí)就沒飯吃了,后端猿三天不學(xué)習(xí)仍舊有白米飯擺于桌前。IT行業(yè)的快速發(fā)展一直在推動著前端技術(shù)棧在不斷地更新?lián)Q代,前端的發(fā)展成了互聯(lián)網(wǎng)時代的一個縮影。而單頁面應(yīng)用的發(fā)展...

    PumpkinDylan 評論0 收藏0
  • SPA那點事

    摘要:單頁面應(yīng)用的出現(xiàn)依然存在著爭議性,我們該如何看待他的兩面性呢接下來小生給大家總結(jié)一下他的優(yōu)缺點。單頁面應(yīng)用的優(yōu)勢無刷新體驗沒有了令人詬病的頁面頻繁刷新,同時節(jié)約瀏覽器資源,路由響應(yīng)比較及時,提升了用戶的體驗。 前端猿一天不學(xué)習(xí)就沒飯吃了,后端猿三天不學(xué)習(xí)仍舊有白米飯擺于桌前。IT行業(yè)的快速發(fā)展一直在推動著前端技術(shù)棧在不斷地更新?lián)Q代,前端的發(fā)展成了互聯(lián)網(wǎng)時代的一個縮影。而單頁面應(yīng)用的發(fā)展...

    Lsnsh 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<