Appearance
路由模式
前端路由
浏览器的路由模式有两种:history 和 hash 模式,他们的表现形式都是在 url 呈现的,只不过 hash 模式以 hash 值表述,history 模式以模拟路径表示,他们两个相同点都是值发生变化时都不会导致 http 请求,比较大的不同点是第一次加载页面时,会发生一次网络请求加载 html 资源,但是 hash 值不会被后端接受到,而 history 模式下对应的模拟路径也会被当成请求的路径,从而会导致不能正确的加载 html 资源。
一个 URL 信息可以从 location 对象可以看出,如(http://127.0.0.1:3001/sadasd?op=8#/dsad)
会被解析成:
host:'127.0.0.1:3001' 主机名
pathname:'/sadasd'
port:'3001'
hash:'#/dasd'
protocol:'http:',
search:'?op=8'
....
hash 模式
hash 模式的原理就是通过监听,url 上的 hash 值变化,根据当前 hash 值与路由表进行匹配,从而渲染对应内容。如何监听 hash 值的变化呢?使用 onhashchange 即可监听浏览器 hash 值变化了,hash 值变化从之执行相关操作即可。
js
// 路由表
const routes = [
{
path: "/home",
template: "<h1>this is home</h1>",
},
{
path: "/user",
template: "<div>this is user</div>",
},
];
// hash值变化时
window.onhashchange = (ev) => {
// ev为一个事件对象,包含了新旧的url值等等
const path = ev.newURL.split("#")[1];
// 解析出路由路径后,进入路由表进行匹配,渲染对应内容
routes.some((ele) => {
if (ele.path === path) {
body.innerHTML = ele.template;
return true;
}
});
};
// 路由表
const routes = [
{
path: "/home",
template: "<h1>this is home</h1>",
},
{
path: "/user",
template: "<div>this is user</div>",
},
];
// hash值变化时
window.onhashchange = (ev) => {
// ev为一个事件对象,包含了新旧的url值等等
const path = ev.newURL.split("#")[1];
// 解析出路由路径后,进入路由表进行匹配,渲染对应内容
routes.some((ele) => {
if (ele.path === path) {
body.innerHTML = ele.template;
return true;
}
});
};
history 模式
history 模式主要是使用 pushState、replaceState 这两个 API 实现 url 上 pathname 的变化,而 popState 做为 window 上的事件监听,可以监听浏览器前进或后退,从而执行渲染对应内容。
API
history.pushState(state,title,path)
第一个参数可以作为路由传参的方式来保存数据?
第二个是浏览器标题,一般传入空串即可,大部分浏览器会忽略该参数
第三个是 path 路径,调用后 url 的 pathname 就会变成对应的 path 值。
ts
history.pushState({}, "", "home");
history.pushState({}, "", "home");
调用后 url 上的 pathname 就会变成第三个参数的值,然后就可以根据 pathname 来匹配路由,从而渲染对应路由视图,注意调用 pushState 或 replaceState 都不会触发 popstate 事件。
事件 popState
popState 会在浏览器前进后退时会触发,函数可以接受到一个事件对象,里面有对应 pushState 时传入的 state,事件触发后可以根据当前 pathname 匹配路由表来渲染对应路由