成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

自己動(dòng)手實(shí)現(xiàn)一個(gè)前端路由

longshengwang / 1557人閱讀

摘要:監(jiān)聽的變動(dòng)省略其他代碼省略其他代碼這樣,我們就初步實(shí)現(xiàn)了一個(gè)路由,那么接下來,我們來看看路由怎么實(shí)現(xiàn)。

前言

用過現(xiàn)代前端框架的同學(xué),對(duì)前端路由一定不陌生, vue, react, angular 都有自己的 router, 那么你對(duì) router 的工作原理了解嗎?
如果還不了解, 那么請(qǐng)跟我一起來手寫一個(gè)簡(jiǎn)單的前端路由, 順便了解一下.

實(shí)現(xiàn)路由的2種方式

hash模式

history模式

缺點(diǎn):

hash:丑(地址欄要多一個(gè)#), 某些特殊場(chǎng)景有坑 ,如微信支付回調(diào)

history: 兼容性較差, 直接訪問會(huì)400 ,除非后端或者服務(wù)器有做處理

基本原理

hash是基于 監(jiān)聽 hashchange 事件實(shí)現(xiàn)的,history 是基于 pushState 和 popState,

實(shí)現(xiàn)

由于history兼容性較差,而且實(shí)現(xiàn)方式基本沒多大區(qū)別,本文就以hash模式來實(shí)現(xiàn),history的實(shí)現(xiàn)方式只實(shí)現(xiàn)不同的部分。



    
    Document





以上就是hash模式的最簡(jiǎn)單實(shí)現(xiàn),查看控制臺(tái),可以看到不管是點(diǎn)擊跳轉(zhuǎn)按鈕,還是點(diǎn)擊瀏覽器的前進(jìn)/后退按鈕,控制臺(tái)都會(huì)輸出當(dāng)前頁面對(duì)應(yīng)的 "url",有了 "url",我們就可以對(duì)內(nèi)容做條件渲染了

我們?cè)谏厦娴拇a的基礎(chǔ)上,稍作修改一下,增加2個(gè)div,一個(gè)是login,一個(gè)是index



    
    Document
    




這樣,我們就能根據(jù)不同的hash地址,顯示不同的內(nèi)容,是不是已經(jīng)有點(diǎn)路由的味道了呢?但是目前還無法傳參,傳參的方式有很多種,最常見最通俗的,應(yīng)該是query string 了吧? query string 其實(shí)很簡(jiǎn)單,解析url即可。

    // 監(jiān)聽hash的變動(dòng)
    window.addEventListener("hashchange", function (e) {
        let url = location.hash.slice(1) || "index"
        // 解析url
        let questionIndex = url.indexOf("?")
        let path, query
        if(questionIndex >= 0){
            path = url.substr(0,questionIndex)
            let queryString = url.substr(questionIndex+1)
            let queryArray = queryString.split("&")
            let queryObject = {}
            queryArray.map(str => {
                let equalIndex = str.indexOf("=")
                if(equalIndex > 0) {
                    let key = str.substr(0,equalIndex)
                    let value = str.substr(equalIndex+1)
                    queryObject[key] = value
                }
            })
            query = queryObject
        } else {
            path = url
            query = {}
        }
        
        console.log("接收到的參數(shù)", query)
        setVisible(path)
    })

這樣,我們就能獲取到URL上傳遞的query string , 還順便解決了傳參會(huì)導(dǎo)致路由解析不正確的bug.

傳參其實(shí)還有個(gè)更簡(jiǎn)單的方法,就是 設(shè)置一個(gè)全局變量 param,然后在需要傳值的時(shí)候,直接對(duì)param 賦值即可

    // 設(shè)置一個(gè)全局變量
    var param = {}
    // 頁面跳轉(zhuǎn)
    // 這個(gè)多了個(gè)參數(shù) args
    function hashPush(url, args) {
        location.hash = "#" + url
        param = args
    }

由于是全局變量,所以可以在任意位置使用 param,不過這樣直接使用全局變量的方式,也有它的弱點(diǎn),就是點(diǎn)擊返回按鈕的時(shí)候無法保存變量,而query string 因?yàn)槭窃?url 里面的,所以返回的時(shí)候,可以拿到上個(gè)頁面的 query string,
那我們有沒有辦法讓全局變量的方式也能保存上一個(gè)頁面的參數(shù)呢? 我們來稍微修改一下代碼

    // 設(shè)置一個(gè)全局變量
    var param = {}
    // 頁面跳轉(zhuǎn)
    // 這個(gè)多了個(gè)參數(shù) args
    function hashPush(url, args) {
        location.hash = "#" + url
        // 如果有傳args參數(shù),就在 param 對(duì)象下建一個(gè)名字跟當(dāng)前url一樣的對(duì)象,并把a(bǔ)rgs賦值給它
        if(args) {
            param[url] = args
        }
    }

那我們?cè)?hashchange 的時(shí)候,可以根據(jù)url來定位該頁面的參數(shù)。

    // 監(jiān)聽hash的變動(dòng)
    window.addEventListener("hashchange", function (e) {
        // 省略其他代碼
        args = param[path] || {}
        // 省略其他代碼
    })

這樣,我們就初步實(shí)現(xiàn)了一個(gè)hash路由,那么接下來,我們來看看history路由怎么實(shí)現(xiàn)。

history 模式

history 模式主要依靠 調(diào)用 history.pushState() 方法 和 監(jiān)聽 popstate 事件。

history.pushState() 方法接收3個(gè)參數(shù):

要傳遞的數(shù)據(jù)(參數(shù))

給頁面設(shè)置的標(biāo)題(兼容性差,幾乎沒用)

url

我們看看調(diào)用實(shí)例

    history.pushState({id:1}, "我是頁面標(biāo)題", url)

需要注意的是 pushState 的時(shí)候,并不會(huì)觸發(fā) popstate 事件,只有在前進(jìn)后退的時(shí)候,才會(huì)觸發(fā),所以 pushState 之后,需要手動(dòng)去設(shè)置頁面的相關(guān)狀態(tài)。如上面的例子,我們需要這樣做

    history.pushState({id:1}, "我是頁面標(biāo)題", url)
    setVisible(url)

然后監(jiān)聽 popstate 事件,捕獲 前進(jìn)/后退

 window.addEventListener("popstate",function (e) {
     // e.state 就是你 pushState 的時(shí)候,傳的第一個(gè)參數(shù)
     let state = e.state || {}  
     let url = state.target.location.pathName
     //  根據(jù)參數(shù) 做一些其他操作
  })
最后

本文最終實(shí)現(xiàn)代碼已經(jīng)放在 github上,想要直接看效果的同學(xué),可以上去直接copy,運(yùn)行。

如果覺得本文對(duì)您有用,請(qǐng)給本文的github加個(gè)star,萬分感謝

另外,github上還有其他一些關(guān)于前端的教程和組件,有興趣的童鞋可以看看,你們的支持就是我最大的動(dòng)力。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95794.html

相關(guān)文章

  • 自己動(dòng)手實(shí)現(xiàn)一個(gè)前端路由

    摘要:?jiǎn)雾撁鎽?yīng)用利用了動(dòng)態(tài)變換網(wǎng)頁內(nèi)容避免了頁面重載路由則提供了瀏覽器地址變化網(wǎng)頁內(nèi)容也跟隨變化兩者結(jié)合起來則為我們提供了體驗(yàn)良好的單頁面應(yīng)用前端路由實(shí)現(xiàn)方式路由需要實(shí)現(xiàn)三個(gè)功能瀏覽器地址變化切換頁面點(diǎn)擊瀏覽器后退前進(jìn)按鈕,網(wǎng)頁內(nèi)容跟隨變化刷新瀏 單頁面應(yīng)用利用了JavaScript動(dòng)態(tài)變換網(wǎng)頁內(nèi)容,避免了頁面重載;路由則提供了瀏覽器地址變化,網(wǎng)頁內(nèi)容也跟隨變化,兩者結(jié)合起來則為我們提供了體...

    psychola 評(píng)論0 收藏0
  • webpack+vue項(xiàng)目實(shí)戰(zhàn)(三,配置功能操作頁和組件的按需加載)

    摘要:但是實(shí)際上,回款管理和開票管理的組件文件也是加載了。所以下面引用按需加載來處理。是不是小很多了,然后和是按需加載的,就是需要的時(shí)候才加載。 1.前言 上篇文章(webpack+vue項(xiàng)目實(shí)戰(zhàn)(二,開發(fā)管理系統(tǒng)主頁面)),實(shí)現(xiàn)了,側(cè)邊欄的一個(gè)操作,點(diǎn)擊側(cè)邊欄的一些操作,最重要的就是路由的切換。看了上一篇的伙伴也不難發(fā)現(xiàn),除了點(diǎn)擊側(cè)邊欄‘首頁’之外,點(diǎn)擊其它的都是白色的一片。原因我想大家都...

    endless_road 評(píng)論0 收藏0
  • 記一次vue仿網(wǎng)易云音樂的單頁面應(yīng)用

    摘要:說明一直想做一個(gè)基于的項(xiàng)目但是因?yàn)轫?xiàng)目往往要涉及到后端的知識(shí)不會(huì)后端真的苦所以就沒有一直真正的動(dòng)手去做一個(gè)項(xiàng)目。直到發(fā)現(xiàn)上有網(wǎng)易云音樂的才開始動(dòng)手去做。僅僅完成了首頁登入,歌單,歌曲列表頁。 說明 一直想做一個(gè)基于VUE的項(xiàng)目,但是因?yàn)轫?xiàng)目往往要涉及到后端的知識(shí)(不會(huì)后端真的苦),所以就沒有一直真正的動(dòng)手去做一個(gè)項(xiàng)目。直到發(fā)現(xiàn)GitHub上有網(wǎng)易云音樂的api NeteaseCloud...

    hqman 評(píng)論0 收藏0
  • 使用next.js結(jié)合GITHUB ISSUE實(shí)現(xiàn)博客。

    摘要:而更多的應(yīng)用采用的是簡(jiǎn)單的同構(gòu)實(shí)現(xiàn)。請(qǐng)使用動(dòng)態(tài)路由進(jìn)行處理。后來用布署頻繁調(diào)試,發(fā)現(xiàn)自定義在上并不能用,看建議使用動(dòng)態(tài)路由。如果要取消這種行為可以使用方法。利用動(dòng)態(tài)實(shí)現(xiàn)代碼塊切片。如果使用的話,建議使用動(dòng)態(tài)路由去做布署啦。 使用next.js結(jié)合GITHUB ISSUE實(shí)現(xiàn)博客。 起因 。。。。起因是因?yàn)樵谀尘W(wǎng)站看到有一些類似實(shí)現(xiàn)。打算自己也做個(gè)side-project。 習(xí)慣性的對(duì)自...

    SillyMonkey 評(píng)論0 收藏0
  • JS或Jquery

    摘要:大潮來襲前端開發(fā)能做些什么去年谷歌和火狐針對(duì)提出了的標(biāo)準(zhǔn),顧名思義,即的體驗(yàn)方式,我們可以戴著頭顯享受沉浸式的網(wǎng)頁,新的標(biāo)準(zhǔn)讓我們可以使用語言來開發(fā)。 VR 大潮來襲 --- 前端開發(fā)能做些什么 去年谷歌和火狐針對(duì) WebVR 提出了 WebVR API 的標(biāo)準(zhǔn),顧名思義,WebVR 即 web + VR 的體驗(yàn)方式,我們可以戴著頭顯享受沉浸式的網(wǎng)頁,新的 API 標(biāo)準(zhǔn)讓我們可以使用 ...

    CatalpaFlat 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<