21.框架通识-路由
单页面应用原理
单页面应用的特征,说穿了就是两点:
1.通过 js 能够改变浏览器地址栏的地址,然后页面也跟着改变,但是不会重新加载页面。
想通过 js 能够改变浏览器地址栏的地址,很简单,比如对location.href,或者location.pathname进行赋值,但这会导致浏览器会重新加载一个目标页面。要想不重新加载页面有两种方式:一是对 location.hash 进行赋值,二是使用 histrory 对象的 pushState 或 replaceState 方法。还剩最后一个问题,如何让页面也跟着改变?如果我能监听到地址栏变化,然后调用函数(比如叫updateView)更新页面就行了。
如:
window.onTheUrlChange = function updateView() {}
如果不能监听到的话,那直接在改变地址栏后,再去调用updateView也行。
function toggleRoute() {
changeURL();
updateView();
}
幸运的是,还真能监听到地址栏变化。
window.onhashchange、window.onpopstate这两个api,不仅能监听到对location.hash的赋值,或者调用histrory.pushState\histrory.replaceState导致的地址栏改变,而且还能监听到浏览器前进、后退按钮带来的地址栏改变,或者history.go(-1)之类的,总之,只要是地址栏的改变,都能被捕获。
2.能恢复刷新前的页面
window.onhashchange、window.onpopstate有个小问题,刷新页面时两者都不会被触发。但是刷新又天然的会重新加载页面,导致刷新前的页面丢失。比如我们自应用首页进入了about页面,此时刷新浏览器,页面被重新加载,所以我们又回到了首页。这时候可以用load事件,根据当前url中的信息,知道应该渲染的是about。所以调用updateView('about')就行。
路由的实现方式 url的组成部分:
http:127.0.0.1:80/main/doc?lang=cn#part/1
协议
| 主机地址
| 端口
| 路径(pathname)
| search
| hash
pathname部分(/main/doc),刷新时会被带进重新请求的url中
hash部分(part/1),刷新时会被忽略掉
所以刷新后的请求url是
http:127.0.0.1:80/main/doc?lang=cn
方式一:hash 模式
location.hash + hashchange
【21.框架通识-路由】原理:通过location.hash 改变地址栏hash,监听地址栏hash变化,更新视图
- 当点击导航元素时,对location.hash进行赋值,触发hashchange
- 当点击浏览器前进后退按钮时,触发hashchange
- 当手动改变地址栏然后enter时以及当F5刷新时,hash部分,不会被加入到请求路径中,(如
http:127.0.0.1:80/main/doc?lang=cn#part/1
刷新,浏览器发送请求url是http:127.0.0.1:80/main/doc?lang=cn
)
无法监听到hashchange事件,则通过load事件来更新视图
$('.btn').click(function() {
location.hash = 'user'
})window.onhashchange = function() {
$('router-outlet').html(user-template)
}window.onload = function() {
const path = location.hash;
const template = getTemplate(path);
$('router-outlet').html(template)
}
?
方式二:history模式
history.pushState() + popstate
因为history模式,路由信息部分是加到url的pathname部分的,所以刷新时,路由信息会被添加到请求中,如果服务端不处理,会导致404,所以需要服务端配合重定向。只要收到对某个路由的请求,统一返回index.html。
$('.btn').click(function() {
let data = https://www.it610.com/article/{name:'张三'};
history.pushState(data, '', 'user/zhangsan');
$('router-outlet').html(template)
})window.onpopstate = function() {
$('router-outlet').html(user-template)
}// 后端重定向后需要
window.onload = function() {
const path = location.pathname;
const template = getTemplate(path);
$('router-outlet').html(template)
}
框架路由的一些共同点(ngjs\ng\vue) 1.多视图,可以有多个路由容器
2.路由嵌套,可以层层嵌套
3.路由参数,参数都有三种形式
- 动态路由参数,出现在url的pathname部分
- params
- query ,出现在url的search部分
推荐阅读
- android第三方框架(五)ButterKnife
- 标签、语法规范、内联框架、超链接、CSS的编写位置、CSS语法、开发工具、块和内联、常用选择器、后代元素选择器、伪类、伪元素。
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了
- 【秀娟习惯养成记—2021.3.11】
- 构建App(一)(框架与结构)
- 2021.4.8日《我们为什么无法摆脱慢性疾病》常斌
- laravel框架泛解
- spring事务管理_01:事务管理框架+声明式事务
- 2021.5.5|2021.5.5 五一第五天
- 2021.5.27阅读思考题