1 概述
前端路由是指,不同的url展示不同的页面,例如Vue React中,虽然是单页面,但是通过路由还是实现了我们想要的功能。
前端路由的模式分为两种:
- hash模式:http://localhost/Day/hash.html#/home 存在一个 # 符号,和普通的url相比有些丑
- history模式:http://localhost/home 这和普通的URL没有区别,非常好看
那么这两种模式的实现原理是什么呢?
2. hash模式(简单一些)
主要使用:window.location.hash 和 onhashchange() 来实现的;
实现的代码如下:需要在Apach服务下运行,具体的可以评论问我!
<!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>hash</title>
</head>
<body>
<button class="router" to="/home">首页</button>
<button class="router" to="/content">内容</button>
<div class="router-view">
</div>
<script>
var btn=document.getElementsByClassName("router");
var view=document.getElementsByClassName("router-view")[0];
routes=[
{"path":"/home", "component":"<p>我是首页的组件</p>"},
{"path":"/content", "component":"<p>我是内容的组件</p>"}
]
// 当hash值发生改变时,显示不同的内容 这是进入页面时触发的
var hash=window.location.hash;
if(hash){
var url=hash.substring(1)
renderView(url);
}else{
window.location.hash="/";
}
// 点击时,使得hash值发生改变,也就使得显示改变
for(var i=0;i<btn.length;i++){
btn[i].onclick=function(){
var hash=this.getAttribute("to");
renderView(hash);
}
}
//hash值改变时 这是hash值发生改变时触发的
// 历史回退
window.onhashchange=function(){
var hash=window.location.hash;
if(hash){
var url=hash.substring(1)
renderView(url);
}else{
window.location.hash="/";
}
}
function renderView(url){
for(var i=0;i<routes.length;i++){
if(routes[i]["path"]==url){
view.innerHTML=routes[i]["component"];
window.location.hash=url;
}
}
}
</script>
</body>
</html>
3 history模式(复杂一些)
主要使用:window.location.pathname 、history.pushState() 和 onpopstate() 来实现的;
实现的代码如下:同样需要在Apach服务下运行,具体的可以评论问我!
这里需要注意的是:要想使用history模式,必须在后端配置一个文件 配置说明:https://router.vuejs.org/zh/guide/essentials/history-mode.html 文件名取为 .htaccess
<!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>hash</title>
</head>
<body>
<button class="router" to="/home">首页</button>
<button class="router" to="/content">内容</button>
<div class="router-view">
</div>
<script>
// history 模式 pushState + onpopState事件
// 要想使用history模式,必须在后端配置一个文件 配置说明:https://router.vuejs.org/zh/guide/essentials/history-mode.html
// 文件名取为 .htaccess
var btn=document.getElementsByClassName("router");
var view=document.getElementsByClassName("router-view")[0];
routes=[
{"path":"/home", "component":"<p>我是首页的组件</p>"},
{"path":"/content", "component":"<p>我是内容的组件</p>"}
]
// 输入路径,对应的匹配
var url=window.location.pathname.substring(4);
renderView(url);
// 点击时
for(var i=0;i<btn.length;i++){
btn[i].onclick=function(){
var url=this.getAttribute("to");
renderView(url);
}
}
// 历史回退 监听历史管理发生改变
window.onpopstate=function(ev){
view.innerHTML=ev.state;
}
function renderView(url){
if(url){
for(var i=0;i<routes.length;i++){
if(routes[i]["path"]==url){
view.innerHTML=routes[i]["component"];
// window.location.pathname="/Day"+url; //我一开始想看能不能直接设置,结果发现不能
// 因为改变window.location.pathname会导致页面再次刷新,那也这就死循环了
// 所以要想其他的办法来改变url
// 所以就出现了history.pushState()
// 第一个参数:存储进历史管理的数据
// 第二个参数:历史管理的title(还没实现,但需要占位)
// 第三个参数: 路由的地址
history.pushState(routes[i]["component"],"",url);
//这就实现了
}
}
}
}
</script>
</body>
</html>