HashRouter的实现原理,带你一起手写。

在多页应用的开发中,每个页面都是独立的HTML文件。当用户在应用中导航到新页面时,浏览器会发送全新的HTTP请求到服务器,获取该页面的所有资源(HTML、CSS、Javascript),也就是说,每次页面跳转都会经历一个完整的加载过程,当网速较慢或浏览器性能较低时,就会出现白屏页面,让用户不明所以,直接离开网站。

那么有什么方法既能不刷新整个页面,又能完成页面跳转呢?一起来看看vue3中hashRouter的实现原理.....

一、vue3中的hashRouter

  • import { createRouter, createWebHashHistory } from 'vue-router'引入模块。
  • 实例化并配置路由,
css 复制代码
const router = createRouter({
    history: createWebHashHistory(),
    routes : [
        {
            path: '/home',
            component: ()=>import('../views/Home.vue')
        },
        {
            path: '/bot',
            component: () => import('../views/Bot.vue')
        },
        {
            path: '/hot',
            name:'hot',
            component: () => import('../views/Hot.vue'),
        }
    ]
})
  • 使用createWebHashHistory()创建的路由器会在URL中使用#字符作为前缀来区分不同的路由。
  • URLhash部分为/home时,加载Home.vue组件......
  • hash部分指的是URL#符号后面跟随的字符串。

当我们进行类似导航栏的功能时,只有部分内容被动态更新,而无需重新加载整个页面,提供了非常流畅的用户体验,类似原生应用的感觉,同时可以减少浏览器负载,不需要频繁的请求完整的页面资源。

二、锚链接实现改变URL的hash部分

我们看见了vue3中页面更新时只有URL的hash部分发生了改变,那么有什么方法能改变这部分呢?

使用锚链接

在HTML中,使用<a>标签结合hash来创建锚链接。用户点击锚链接时,window.location.hash将被更新,从而触发hashchange事件,这是接下来hashRouter实现的核心。

三、、手写hashRouter

基本原理

使用纯Javascript来监听hashchange事件,根据hash的变化来更新DOM。

xml 复制代码
<body>
    <nav id="nav">
        <ul>
            <li><a href="#/page1">page1</a></li>
            <li><a href="#/page2">page2</a></li>
            <li><a href="#/page3">page3</a></li>
        </ul>
    </nav>
    <div id="container"></div>
    <script>
        class HashRouter{
            constructor(){
                this.routes = {}  //page => Component
                window.addEventListener('hashchange',
                this.load.bind(this),false)
            }

            register(hash,callback = function(){}){
                this.routes[hash] = callback 
            }
            load(){
                let hash = location.hash.slice(1)  //去掉# 就是路由 
                console.log(hash,'///');
                let handler
                if(!hash){
                    //首页
                    handler = this.routes['/index']
                }else{
                    //相应页面
                    handler = this.routes[hash]
                }
                handler && handler.call(this)
            }
            //注册首页
            registerIndex(callback = function(){}){
                this.routes['/index']  = callback
            }
        }
        let router = new HashRouter()
        let container = document.getElementById('container')
        router.registerIndex(()=>{
            container.innerHTML = '我是首页'
        })
        router.register('/page1',()=>{
            container.innerHTML = '我是page1'
        })
        router.register('/page2',function(){
            console.log(this,this.routes);
            container.innerHTML = '我是page2'
        })
        router.register('/page3',()=>{
            container.innerHTML = '我是page3'
        })
        console.log(router.routes);//查看添加的方法,用于handler执行
        router.load()
    </script>
</body>
  • hashchage事件监听器,监听hash部分的内容变化。
  • 注册路由函数register,接收两个参数,一个为要注册路由的hash部分,一个为回调函数。
  • 加载路由函数load,获取URL中的hash部分,输出控制台,清晰明了的看一下是什么东西,handle函数,执行对应hash部分的routes中的函数,用于相应页面的显示。
  • 如果hash部分为空,则执行routes中'/index'所对应的函数,如果不为空,执行相应hash部分的函数,并显示相应页面。
  • handler && handler.call(this)判断routes中是否存在handler是很有必要的,因为用户在输入URL中可能输错,这是handlerundefined,程序崩溃,这样使代码更加健壮。.call确保了函数内部的this正确指向HashRouter实例对象,方便拿到实例对象的所有信息,便于后续操作。
  • 单独创建注册首页函数,功能和注册路由函数register差不多。

实例化HashRouter对象,执行构造函数constructor中的逻辑。 注册几个页面的路由,实际上是往构造函数中的this.routes = {}中添加方法,用于handler的执行。router.load()完成进页面时的首次加载。

我们在看一下routes中的内容和handle函数的this指向。

handler执行routes中'/page2'对应的函数时,this指向的是实例对象HashRouterroutes的内容是对应hash部分内容和执行函数(改变container.innerHTML模拟页面改变)

相关推荐
m0_748235242 分钟前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240251 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar1 小时前
纯前端实现更新检测
开发语言·前端·javascript
寻找沙漠的人2 小时前
前端知识补充—CSS
前端·css
GISer_Jing2 小时前
2025前端面试热门题目——计算机网络篇
前端·计算机网络·面试
m0_748245522 小时前
吉利前端、AI面试
前端·面试·职场和发展
理想不理想v2 小时前
webpack最基础的配置
前端·webpack·node.js
pubuzhixing2 小时前
开源白板新方案:Plait 同时支持 Angular 和 React 啦!
前端·开源·github
2401_857600952 小时前
SSM 与 Vue 共筑电脑测评系统:精准洞察电脑世界
前端·javascript·vue.js
2401_857600952 小时前
数字时代的医疗挂号变革:SSM+Vue 系统设计与实现之道
前端·javascript·vue.js