前端路由原理

一.路由底層實(shí)現(xiàn)方式

1.利用監(jiān)聽(tīng)hash變化

<body>
    <a href='#/a'>a</a>
    <a href='#/b'>b</a>
 
    <script type="text/javascript">
      window.addEventListener('hashchange', () => {
        console.log(window.location.hash);
      })
    </script>
</body>
瀏覽器會(huì)監(jiān)聽(tīng)對(duì)應(yīng)的變化

2.利用HTML5 模式的History

<body>
    <a onClick="push('/a')" >a</a>
    <a onClick="push('/b')" >b</a>
 
    <script type="text/javascript">
     
    function push(path) {
      history.pushState({b: path}, null, path);
    }
    </script>
  </body>
image

瀏覽器地址自動(dòng)改變,并且不會(huì)帶有#號(hào)

兩種模式對(duì)比

  1. Hash 模式只可以更改 # 后面的內(nèi)容,History 模式可以通過(guò) API 設(shè)置任意的同源 URL
  2. History 模式可以通過(guò) API 添加任意類型的數(shù)據(jù)到歷史記錄中,Hash 模式只能更改哈希值,也就是字符串
  3. Hash 模式無(wú)需后端配置,并且兼容性好。History 模式在用戶手動(dòng)輸入地址或者刷新頁(yè)面的時(shí)候會(huì)發(fā)起 URL 請(qǐng)求,后端需要配置 1index.html 頁(yè)面用于匹配不到靜態(tài)資源的時(shí)候

二、簡(jiǎn)易版哈希方式實(shí)現(xiàn)路由

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <meta name="author" content="">
    <title>原生模擬 Vue 路由切換</title>
    <style type="text/css">
        .box,
        #router-view {
            max-width: 1000px;
            margin: 50px auto;
            padding: 0 20px;
        }
    </style>
</head>

<body>
    <div class="box">
        <a href="/home" class="router">主頁(yè)</a>
        <a href="/mine" class="router">我的</a>
        <a href="/team" class="router">組</a>
    </div>
    <div id="router-view"></div>
    <script type="text/javascript">
        function Vue(parameters) {
            let vue = {};
            vue.routes = parameters.routes || [];
            vue.init = function() {
                document.querySelectorAll(".router").forEach((item, index) => {
                    item.addEventListener("click", function(e) {
                        let event = e || window.event;
                        event.preventDefault();
                        window.location.hash = this.getAttribute("href");

                        console.log('lalala');
                    }, false);
                });

                window.addEventListener("hashchange", () => {
                    vue.routerChange();
                });

                vue.routerChange();
            };
            vue.routerChange = () => {
                let nowHash = window.location.hash;
                let index = vue.routes.findIndex((item, index) => {
                    return nowHash == ('#' + item.path);
                });
                if (index >= 0) {
                    document.querySelector("#router-view").innerHTML = vue.routes[index].component;
                } else {
                    let defaultIndex = vue.routes.findIndex((item, index) => {
                        return item.path == '*';
                    });
                    if (defaultIndex >= 0) {
                        window.location.hash = vue.routes[defaultIndex].redirect;
                    }
                }
            };

            vue.init();
        }

        new Vue({
            routes: [{
                path: '/home',
                component: "<h1>主頁(yè)</h1>"
            }, {
                path: '/mine',
                component: "<h1>我的</h1>"
            }, {
                path: '/team',
                component: '<h1>組</h1>'
            }, {
                path: '*',
                redirect: '/home'
            }]
        });
    </script>
</body>

</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容