美文网首页Vue
前端路由原理

前端路由原理

作者: 野蛮生长_ed2e | 来源:发表于2019-08-23 16:04 被阅读0次

    一.路由底层实现方式

    1.利用监听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>
    
    浏览器会监听对应的变化

    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

    浏览器地址自动改变,并且不会带有#号

    两种模式对比

    1. Hash 模式只可以更改 # 后面的内容,History 模式可以通过 API 设置任意的同源 URL
    2. History 模式可以通过 API 添加任意类型的数据到历史记录中,Hash 模式只能更改哈希值,也就是字符串
    3. Hash 模式无需后端配置,并且兼容性好。History 模式在用户手动输入地址或者刷新页面的时候会发起 URL 请求,后端需要配置 1index.html 页面用于匹配不到静态资源的时候

    二、简易版哈希方式实现路由

    <!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">主页</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>主页</h1>"
                }, {
                    path: '/mine',
                    component: "<h1>我的</h1>"
                }, {
                    path: '/team',
                    component: '<h1>组</h1>'
                }, {
                    path: '*',
                    redirect: '/home'
                }]
            });
        </script>
    </body>
    
    </html>
    

    相关文章

      网友评论

        本文标题:前端路由原理

        本文链接:https://www.haomeiwen.com/subject/lsstectx.html