浏览器端路由方式有两种: hash 和 history;
hash: 改变瞄点(#)后面的值 获取hash 值: location.hash 包括#(如果有多个井号的话 获取的是第一个井号后面的值)以及后面的值
界面刷新的时候 请求html资源的时候 该值不会向后台发送; 所以如果是这种模式, 不用担心出现丑陋的404界面
hash模式 地址栏地址修改时 会触发 hashchange 事件
window.onhashchange = function() {}
history 模式
该模式下 地址栏地址没有# 就是正常的url 路径 ,刷新界面时 该路径会向后台发送请求,
因为是单页面应用,只有一个index.html , 所以如果输入http://localhost:8887/dtcom?page=1 后台找不到该界面,就会报
所以我们需要在nginx 里面进行配置 (我是在nginx 里面配置的)
try_files $uri $uri/ /index.html;
统一指向index.html ;这样就可以访问了。这个时候 服务器不会再报404;
另外一般都会再写一个万能路由来显示 我们未找到的路由界面
{
path: '*',
name: 'notFound',
component: resolve => require(['@/views/notFound/error.vue'], resolve),
meta: {
title: '出错啦404, 界面未找到'
}
}
这种模式 可以通过window.history.pushState(state, title, url) / window.history.replaceState(state, title, url) 添加,url 必须是同源链接,不然会报错, 第一种会像历史记录栈添加一条记录, 而 replace 则不会, 这两个方法 不会触发popstate 监听, 手动回退、前进浏览器/ window.history.go()/ window.history.forward() / window.history.back 都会触发popstate
window.onpopstate = function(state) {}
假如现在有三个界面
在test.html 中:
调用 window.location.href = 'hash.html' 这个会跳转到hash.html 并且刷新界面
但是如果只是修改hash 值 就不会刷新界面,只是地址栏地址发生了变化
window.location.href = '#/hash.html'
window.history.pushState({},'hash界面', 'hash.html') 也只是地址栏地址发生变化, 没有刷新界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<!-- <link rel="icon" href="<%= BASE_URL %>favicon.ico"> -->
<!-- <link rel="stylesheet" type="text/css" href="../src/assets/css/style.css" rel="external nofollow"> -->
<!-- <script src="<%= VUE_APP_SDK_URL %>"></script> -->
<!-- <script src="../node_modules/vue/dist/vue.js"></script> -->
<!-- <script src="../node_modules/vue-router/src/index.js"></script> -->
<title></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="test">
<div>消息</div>
<!-- <div>{{msg}}</div> -->
<div id="tohash" @click="pushToHash">跳转到hash</div>
</div>
<!-- built files will be auto injected -->
</body>
<script>
const hashEl = document.getElementById('tohash')
hashEl.onclick = function() {
console.log('地址跳转')
// 改变路径 不刷新界面 静态刷新界面数据
// history =====
window.history.pushState({},'hash界面', '/#/hash.html')
// window.history.pushState({},'hash界面', 'hash.html')
// window.history.pushState({},'hash界面',
// 'http://127.0.0.1:5555/public111/#/hash.html')
//window.history.pushState({},'hash界面', '/hash.html') // 地址为相对路径 那就是 origin + //该路径
// window.history.pushState({page: 1}, "title 1", "?page=1")
// window.history.pushState({page: 2}, "title 2", "http://www.baidu.com")
// hash ===== 路径跳转带# 会触发浏览器的前进后退 就是看hash 值有没有变
// window.location.hash = 'index'
// window.location = '#/hash.html?page=2'
// window.location.href = '#/hash.html'
// window.location.replace('/#/hash.html')
// 会刷新界面 跳转界面 重新载入属性
// window.location.replace('hash.html')
// window.location.href = 'hash.html'
// window.location.href = '/#/hash.html'
// window.location.replace('http://127.0.0.1:5555/public111/#/hash.html')
}
window.onhashchange = function() {
console.log('hashchange 可以监听hash 地址路径发生变化')
}
// pushState replaceState 不会触发下面的方法 history.go/forward/back 以及hash 地址栏地址
//变化 手动浏览器前进或者后退
window.onpopstate = function(data) {
console.log('onpopstate 地址发生变化', data)
}
</script>
</html>
小知识点:
路径 分为绝对路径(完整网站地址 http://xxx)/或者相对路径( xxx/xxx/xxx )或者 相对于根目录(/xxxx/xxx/xxx以斜线开头)
假如当前地址是: http://127.0.0.1:5555/public/test.html 在这个界面上点击按钮去跳转
那么origin = http://127.0.0.1:5555
当去跳转的时候 后面的路径可以是相对路径 也可以是绝对路径,或者其他形式(请往下看) history.pushState/ replace/location.hash 无论是哪种路径 都不会去重载刷新界面, 但是location.href/ replace 确不是
如果只是修改hash值 则location.href/ replace 不会去重载界面
比如location.href('#/hash.html ') ;其他情况都会重载界面
1) 若是绝对路径
路径变为: http://127.0.0.1:5555/public/hash.html
window.history.pushState({},'hash界面', 'http://127.0.0.1:5555/public/hash.html')
location.href('http://127.0.0.1:5555/public/hash.html ')
2) 若是以/ 相对于根目录
路径变为: http://127.0.0.1:5555/hash.html
window.history.pushState({},'hash界面', '/hash.html')
location.href('/hash.html ')
3) 以相对路径 xxx/ xxx 这种形式 不是以/ 开头的 ; 如果是#开头 location.href 不会重载界面, 否则重载界面
路径变为: http://127.0.0.1:5555/public/public1/hash.html
window.history.pushState({},'hash界面', 'public1/hash.html')
location.href('public1/hash.html ')
4)单独一个字符串的形式, 和3一样
路径变为: http://127.0.0.1:5555/public/ffff
window.history.pushState({},'hash界面', 'ffff')
location.href('ffff ')
pushState/replacestate
改变的如果是hash 不会触发onhashchange 事件,
hash/replace 改变hash路径会触发onhashchange 和 onpopstate
let btnPush = document.getElementById('push')
btnPush.addEventListener('click', function () {
// alert('1111')
// window.location.hash = '/publictest'
window.location.replace('#/publictest')
// window.history.pushState({}, '', '#/publictest')
})
window.onhashchange = function () {
console.log('onhashchange路径变化')
}
window.onpopstate = function () {
console.log('onpopstate路径变化')
}
学习参考: