前端路由实现原理(history)

了解:

HTML5 history新增了两个API:history.pushState和history.replaceState

两个api都接受三个参数

  • 状态对象(state object):一个JavaScript对象,与用pushState()方法创建的新历史记录条目关联。无论何时用户导航到新创建的状态,popstate事件都会被触发,并且事件对象的state属性都包含历史记录条目的状态对象的拷贝。* 标题(title):FireFox浏览器目前会忽略该参数,虽然以后可能会用上。考虑到未来可能会对该方法进行修改,传一个空字符串会比较安全。或者,你也可以传入一个简短的标题,标明将要进入的状态。* 地址(URL): 新的历史记录条目的地址。浏览器不会在调用pushState()方法后加载该地址,但之后,可能会试图加载,例如用户重启浏览器。新的URL不一定是绝对路径;如果是相对路径,它将以当前URL为基准;传入的URL与当前URL应该是同源的,否则,pushState()会抛出异常。该参数是可选的;不指定的话则为文档当前URL。> 相同之处是两个API都会操作浏览器的历史记录,而不会引起页面的刷新。不同之处在于pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录

大家可以先在控制台试试,看看地址栏发生了什么变化

window.history.pushState(null, null, "test");
​
window.history.pushState(null, null, "/test");
​
window.history.pushState(null, null, "#/hello");
​
window.history.pushState(null, null, "?name=");
</code></pre> 

实例演示

建立html文件,index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>前端路由实现</title><style> .warp{width:400px;height:400px;border:1px solid grey;margin:0 auto;}.nav{border-bottom:1px solid grey;}.nav li{display:inline-block;list-style:none;}.nav li a{display:inline-block;text-decoration: none;padding:10px 15px;}.router{padding:20px;}a{cursor: pointer;} </style>
​
</head>
<body><section class="warp"><div class="nav"><ul><li><a href="javascript:void(0)" data-path="index">首页</a></li> <li><a href="javascript:void(0)" data-path="news">新闻</a></li><li><a href="javascript:void(0)" data-path="about">关于</a></li></ul></div><div id="router" class="router"><<img src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script><script src="./router.js"></script" style="margin: auto" />
​
</body>
</html> 

此时的页面为:

引入js文件router.js

(function(){ history.replaceState(null,null,'');//最开始的状态,采用replace直接替换$('#router').html('<p>显示内容区域</p>')$('a').on('click',function(){console.log(this.text)var text = this.text;$('#router').html('<p>'+ text +'</p>')history.pushState(null,null,'#/'+text);})})() 

此时点击导航按钮时

  • 此时当点击不同的导航项的时候,地址栏上的路由进行了对应的改变,展现的内容区域也发生了变化。但是实际上这个并没有实现路由的真正含义。因为内容部分的改变是根据事件的触发而获得当前的内容。

  • 此时如果点击浏览的前进和后退按钮,内容是无法监听到地址栏的变化而作出改变的

在此基础上变动一下实现方式,将router.js改为:

// 状态版
(function(){  var count = [0,0,0] $('#router').html('<p>首页</p>'+count[0]+'<p>新闻</p>'+count[1]+'<p>关于</p>'+count[2]) // history.replaceState(count,null,'');//最开始的状态,采用replace直接替换 for(var i = 0 ; i<$('a').length; i++){ $('a')[i].index = i $('a').eq(i).on('click',function(){ console.log(this.index); var index = this.index; count[index]++; $('#router').html('<p>首页</p>'+count[0]+'<p>新闻</p>'+count[1]+'<p>关于</p>'+count[2]) console.log(count) history.pushState(count,null,'#/count'+count[index]);//之后的状态,需要进行保存 }) } //监听history其他api导致地址栏url改变事件 window.addEventListener('popstate',function(e){ console.log(e.state); var state = e.state; $('#router').html('<p>首页</p>'+state[0]+'<p>新闻</p>'+state[1]+'<p>关于</p>'+state[2]) })
})() 

此时的思路是做一个状态记录,记录下每个导航按钮被点击的次数。当每次执行点击导航栏切换的时候,通过history.pushState(count, null, '#/count'+count[index])这个api,传递了状态对象在内,并在第三个参数中将当前已点击数作为地址栏的显示数据。示例如下:

  • !!当活动历史记录条目更改时,将触发popstate事件。如果被激活的历史记录条目是通过对history.pushState()的调用创建的,或者受到对history.replaceState()的调用的影响,popstate事件的state属性包含历史条目的状态对象的副本。

  • 需要注意的是调用history.pushState()或history.replaceState()不会触发popstate事件。只有在做出浏览器动作时,才会触发该事件,如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back())

此处通过记录下每次的点击次数来解释了pushState的用法以及参数,其实简单的写法可以表达为:

(function(){ var url = '内容展示';history.replaceState(url,null,'');//最开始的状态,采用replace直接替换$('#router').html('<p>'+url+'</p>')$('a').on('click',function(){console.log(this.text)url = this.text;$('#router').html('<p>'+ url +'</p>')history.pushState(url,null,'#/'+url);})window.addEventListener('popstate',function(e){console.log(e.state);url = e.state$('#router').html('<p>'+ url +'</p>') }); 
})() 

现在的效果看上去其实我们相当于回到了远点,但是解决了无法监听地址栏的地址变化问题,是通过监听popstate来作出响应的。

现在还只是看了这一部分的路由实现机制,要通过监听作出不同的响应。还需要更深入的与hash进行对比。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 是一个用于构建 Java 应用程序的开发框架,而 Vue 是一个流行的 JavaScript 框架,用于构建用户界面。在使用 Spring Boot 和 Vue 开发应用程序时,你可以使用 Vue 的 history 路由模式来实现前端路由。 Vue 的 history 路由模式允许在不刷新页面的情况下进行路由切换。它依赖于 HTML5 的 history API,可以通过修改浏览器的 URL 来实现路由切换。相比于 hash 路由模式,history 路由模式的 URL 看起来更加友好,没有 "#" 符号。 要在 Spring Boot 中使用 Vue 的 history 路由模式,你需要进行以下步骤: 1. 在 Vue 项目中配置 history 路由模式。可以通过在 `router/index.js` 文件中添加 `mode: 'history'` 来启用 history 模式。 ```javascript import Vue from 'vue' import Router from 'vue-router' import Home from '@/views/Home.vue' Vue.use(Router) export default new Router({ mode: 'history', routes: [ { path: '/', name: 'Home', component: Home }, // 其他路由配置... ] }) ``` 2. 配置 Spring Boot 后端来支持 history 路由模式。在 Spring Boot 中,你可以通过配置 `WebMvcConfigurer` 来处理前端路由。 ```java @Configuration public class WebMvcConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/{spring:\\w+}") .setViewName("forward:/"); registry.addViewController("/**/{spring:\\w+}") .setViewName("forward:/"); registry.addViewController("/{spring:\\w+}/**{spring:?!(\\.js|\\.css)$}") .setViewName("forward:/"); } @Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setUseSuffixPatternMatch(false); } } ``` 上述代码中的 `WebMvcConfig` 类配置了三个视图控制器,将所有匹配到的 URL 都转发到根路径,以便 Vue 的路由能够处理。`configurePathMatch` 方法用于禁用后缀模式匹配。 通过上述配置,当在 Vue 中使用 history 路由切换时,Spring Boot 会将前端路由的请求转发到 Vue 的入口,然后 Vue 会根据配置的路由规则进行相应的展示。 希望以上信息对你有所帮助!如果你还有其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值