对前端路由的理解

最近在学习vue-router源码,看的有点懵。
刚刚看了一篇文章觉得很不错,看完后没有那么懵了,决定自己理解后记录一下。

带着问题去思考

  • 1.为什么会有前端路由?
  • 2.前端路由解决了什么?
  • 3.前端路由如何实现?

1

在现代框架(Vue-React)等出现前,几乎都是纯dom页面(传统页面),因前端越来越复杂,工程化等,现在大多项目都是单页面应用,单不一样的是,单页面引用就一个app.js,通过JS去渲染,那么如果有几十个页面如何展示呢?

2

此时就出现了前端路由,根据不同地址(pathname)展示不同组件,例如Vue-router和routeView,routeView就是一个占位,通过地址的不同塞入不同的组件。

3

一般使用俩种模式,hash和history模式。

  • hash模式
    通过hashChange方法监听

    可以通过点击a标签改变#/后的url
    可以通过修改window.location改变url
    可以通过浏览器前进

    以上三种方法都可以被监听到

<body>

    <ul>
        <li>
            <a href="#/page1">page1</a>

        </li>
        <li>
            <a href="#/page2">page2</a>
        </li>
    </ul>

    <div id="routeView"></div>

    <script type="text/javascript">

        window.addEventListener('DOMContentLoaded', load)
        window.addEventListener('hashchange', hashChange)
        let routeView = null
        function load() {
            routeView = document.getElementById('routeView')
            hashChange()
        }
        function hashChange() {
            console.log(location.hash);
            switch (location.hash) {
                case '#/page1':
                routeView.innerHTML = 'page1'
                    break;
                case '#/page2':
                routeView.innerHTML = 'page2'
                    break;
                default:
                routeView.innerHTML = 'page'
                    break;
            }
        }

    </script>
</body>
  • history模式
    通过popstate事件实现,不过这个比较麻烦些。
    在这里插入图片描述
    这里需要解决a标签无法被监听的问题,注意思路就是禁用默认事件,然后添加点击回调获取href值然后调用popstate。
    在这里插入图片描述
    在这里插入图片描述
    循环所有a标签,禁止默认事件
    e.preventDefault()
<body>

    <ul>
        <li>
            <a href="/page1">page1</a>

        </li>
        <li>
            <a href="/page2">page2</a>
        </li>
    </ul>

    <div id="routeView"></div>

    <script type="text/javascript">

        window.addEventListener('DOMContentLoaded', Load)
        window.addEventListener('popstate', PopChange)
        var routeView = null
        function Load() {
            routeView = document.getElementById('routeView')
            PopChange()
            let aList = document.querySelectorAll('a[href]')
            console.log(aList);
            // 遍历 a 标签节点数组,阻止默认事件,添加点击事件回调函数
            aList.forEach(aNode => aNode.addEventListener('click', function (e) {
                e.preventDefault() //阻止a标签的默认事件
                let href = aNode.getAttribute('href')
                console.log(href);
                //  手动修改浏览器的地址栏
                                 // state, title, url
                history.pushState(null, '', href)
                // 通过 history.pushState 手动修改地址栏,
                // popstate 是监听不到地址栏的变化,所以此处需要手动执行回调函数 PopChange
                PopChange()
            }))

        }

        function PopChange() {

            console.log('location', location)
            switch (location.pathname) {
                case '/page1':
                    routeView.innerHTML = 'page1'
                    return
                case '/page2':
                    routeView.innerHTML = 'page2'
                    return
                default:
                    routeView.innerHTML = 'page1'
                    return
            }
        }



        // window.addEventListener('DOMContentLoaded', load)
        // window.addEventListener('hashchange', hashChange)
        // let routeView = null
        // function load() {
        //     routeView = document.getElementById('routeView')
        //     hashChange()
        // }
        // function hashChange() {
        //     console.log(location.hash);
        //     switch (location.hash) {
        //         case '#/page1':
        //         routeView.innerHTML = 'page1'
        //             break;
        //         case '#/page2':
        //         routeView.innerHTML = 'page2'
        //             break;
        //         default:
        //         routeView.innerHTML = 'page'
        //             break;
        //     }
        // }

    </script>
</body>

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值