Vue的路由实现:hash模式 和 history模式
hash模式:在浏览器中符号“#”,#以及#后面的字符称之为hash,用window.location.hash读取;
特点:hash虽然在URL中,但不被包括在HTTP请求中;用来指导浏览器动作,对服务端安全无用,hash不会重加载页面。
hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 http://www.xxx.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。
history模式:history采用HTML5的新特性;且提供了两个新方法:pushState(),replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更。
history 模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如 http://www.xxx.com/items/id。后端如果缺少对 /items/id 的路由处理,将返回 404 错误。Vue-Router 官网里如此描述:“不过这种模式要玩好,还需要后台配置支持……所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。”
vue路由的钩子函数
首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
beforeEach主要有3个参数to,from,next:
to:route即将进入的目标路由对象,
from:route当前导航正要离开的路由
next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
案例代码:
<!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>
<style>
#nav {
margin: 0;
border:0;
height: 40px;
border-top: #060 2px solid;
margin-top: 10px;
border-bottom: #060 2px solid;
background-color: red;
}
#nav ul {
margin: 0;
border: 0;
list-style: none;
line-height: 40px;
}
#nav li {
display: block;
float: left;
}
#nav a {
display: block;
color: #fff;
text-decoration: none;
padding: 0 20px;
}
#nav a:hover {
background-color: orange;
}
</style>
</head>
<body>
<h3>使用 hash 实现前端路由</h3>
<hr/>
<a href="#hash1">#hash1</a>
<a href="#hash2">#hash2</a>
<a href="#hash3">#hash3</a>
<a href="#hash4">#hash4</a>
<p/>
<div id = "show-hash-result" style="color:blue">
点击上面链接,并观察浏览器
</div>
<h4>定义一个简单的 tab 路由页面</h4>
<div id="nav">
<ul>
<li><a href="#/index.html">首页</a></li>
<li><a href="#/server">服务</a></li>
<li><a href="#/mine">我的</a></li>
</ul>
</div>
<div id="result"></div>
<script type="text/javascript">
window.addEventListener("hashchange", function(){
//变化后输出当前地址栏中的值
document.getElementById("show-hash-result").innerHTML = "当前的 hash 值是: "+location.hash;
//打印出当前 hash 值
console.log("当前的 hash 值是:"+window.location.hash) ;
});
</script>
<!-- 定义 router 的 js 代码块 -->
<script type="text/javascript">
//自定义一个路由规则
function CustomRouter(){
this.routes = {};
this.curUrl = '';
this.route = function(path, callback){
this.routes[path] = callback || function(){};
};
this.refresh = function(){
if(location.hash.length !=0){ // 如果 hash 存在
this.curUrl = location.hash.slice(1) || '/';
if(this.curUrl.indexOf('/')!=-1){ //这里粗略的把 hash 过滤掉
this.routes[this.curUrl]();
}
}
};
this.init = function(){
window.addEventListener('load', this.refresh.bind(this), false);
window.addEventListener('hashchange', this.refresh.bind(this), false);
}
}
//使用路由规则
var R = new CustomRouter();
R.init();
var res = document.getElementById('result');
R.route('/hash1',function () {
document.getElementById("show-hash-result").innerHTML = location.hash;
})
R.route('/index.html', function() {
res.style.height='150px';
res.style.width='300px';
res.style.background = 'green';
res.innerHTML = '<html>我是首页</html>';
});
R.route('/server', function() {
res.style.height='150px';
res.style.width='300px';
res.style.background = 'orange';
res.innerHTML = '我是服务页面';
});
R.route('/mine', function() {
res.style.background = 'red';
res.style.height='150px';
res.style.width='300px';
res.innerHTML = '我的界面';
});
</script>
</body>
</html>