1、路由是什么?
2、hash模式、history模式、memory模式
1、路由是什么?
家里上网
- 猫:调制解调器,虚拟信号变成数字信号/数字信号变成虚拟信号。
调制器 制器是指通过数字信号处理技术
解调器 调制产生的振荡或波中恢复原调制信号的器件 - 如果有多人上网就需要路由器
people-----路由器------电信(出售网络IP/端口)------百度、腾讯、抖音购买几千个IP作为他的服务器。
上网的时候 你连路由器 路由器看你想连哪里 。
比如想去抖音,路由器把你信号发给了抖音 ,然后抖音就过来了(电信那边太复杂略过)。
分发
只要满足一对多 就叫做分发 就是分别发送到各个地方
路由器主要是用来分发请求的,只要一个东西分发了请求 那这就是路由
这个东西就叫做路由器
路由就是分发请求的东西, 这是上网路由
我们要搞前端路由,
路由(维基百科):
通过互联的网络把信息从源地址传输到目的地地址的活动。
路由发生在OSI网络参考模型中的第三层:网络层。
路由引导分组转送,经过一些中间节点后,到达他们最后的目的地。做成硬件的话称之为路由器。
路由器通常根据路由表(一个存储到各个目的地最佳路径的表)来引导分组转送。
路由器(维基百科):是一种电讯网络设备,提供路由与转送两种重要机制。
前端路由:
我们写一个
用户---路由--四个界面(div)
通过路由判断用户想进哪个页面
我们通过URL来进入不同div
http:/127.00.1/#1 DIV1
http:/127.00.1/#2 DIV2
http:/127.00.1/#3 DIV3
http:/127.00.1/#4 DIV4
根据用户的URL是#X 展示不同的divX
简单的路由实现
注:
- hash就是URL #后面的东西包括#
- 由于JS执行完一遍就结束了,只能更改一次,所以要监听这个事件
- 当URL的片段标识符更改时(#x)将触发hashchange事件
- 默认路由、保底路由、嵌套路由
JS
//默认路由
number = number || 1
//第一遍用于默认页面
let number = window.location.hash.substr(1)
//获取界面
let div = document.querySelector(`#div${number}`)
let app = document.querySelector("#app")
//渲染界面+404路由
if (div){
div.style.display = 'block';
}else{
div = document.querySelector("#div404")
div.style.display = 'block';
}
//展示出来
app.appendChild(div)
window.addEventListener('hashchange',()=>{
console.log("hash 变了")
let number2 = window.location.hash.substr(1)
let div2 = document.querySelector(`#div${number2}`)
let app2 = document.querySelector("#app")
if (div2){
div2.style.display = 'block';
}else{
div2 = document.querySelector("#div404")
div2.style.display = 'block';
}
//把之前的div拿出来并隐藏
app2.children[0].style.display = 'none'
document.body.appendChild(app2.children[0])
app2.appendChild(div2)
})
HTML
<a href="#1">go to 1</a>
<a href="#2">go to 2</a>
<a href="#3">go to 3</a>
<a href="#4">go to 4</a>
<div id="app"></div>
<div id = "div1" style="display: none">1</div>
<div id = "div2" style="display: none">2</div>
<div id = "div3" style="display: none"> 3</div>
<div id = "div4" style="display: none">4</div>
<div id = "div404" style="display: none">404</div>
JS代码优化
function route(){
//第一遍用于默认页面
let number = window.location.hash.substr(1)
let app = document.querySelector("#app")
number = number || 1
let div = document.querySelector(`#div${number}`)
if (!div){
div = document.querySelector("#div404")
}
div.style.display = 'block';
if (app.children.length>0){
//如果有就踢出去
app.children[0].style.display = 'none'
document.body.appendChild(app.children[0])
}
app.appendChild(div)
}
route()
window.addEventListener('hashchange',()=>{
console.log("hash 变了")
route()
})
路由表
自定义hasn和div的对应关系
路由表 保存着去往每个网址的东西 表驱动编程
JS
const div1 = document.createElement('div')
div1.innerHTML = '1'
const div2 = document.createElement('div')
div2.innerHTML = '2'
const div3 = document.createElement('div')
div3.innerHTML = '3'
const div4 = document.createElement('div')
div4.innerHTML = '4'
const routeTable = {
'1':div1,
'2':div2,
'3':div3,
'4':div4,
}
function route(){
let number = window.location.hash.substr(1)
let app = document.querySelector("#app")
number = number || 1
let div = routeTable[number.toString()]
if (!div){
div = document.querySelector("#div404")
}
div.style.display = 'block';
app.innerHTML = ''
app.appendChild(div)
}
route()
window.addEventListener('hashchange',()=>{
console.log("hash 变了")
route()
})
HTML
<a href="#1">go to 1</a>
<a href="#2">go to 2</a>
<a href="#3">go to 3</a>
<a href="#4">go to 4</a>
<div id="app"></div>
<div id = "div404" style="display: none">
404
</div>
嵌套思路:页面中还有页面
路由的三种模式
hash模式 history模式 memory模式?
上面的路由是通过hash做的 #x 进入x页面
我不要#1 我直接/1 行不行
hash模式
使用规则:任何情况都可以用hash做前端路由
缺点:SEO不友好
window.location.hash
hash示例
注:
- 浏览器是不会把#之后的内容发给服务器
- 服务器收不到hash,导致访问baidu.com/#1 baidu.com/#2 服务器认为这些页面会被认为直接访问baidu.com 。
- 这三个页面内容不一样但是只有一个URL
- 没有办法收录你的内容 就叫做SEO不友好
那浏览器怎么展示你的三个页面呢 他会永远只展示默认路由 baidu.com 因为别的会被吃掉
谷歌有针对哈希的seo 但是依然不能跟以前的seo媲美 也没人用。
history模式
只有一种情况可以使用那就是后端将所有前端路由都渲染同一个页面,不管请求什么都得到同一个页面,这个同一页面不能是404
假设baidu.com/ ,/后面是啥都到首页,就可以用history模式
使用条件:
1、后端知道将所有请求都渲染到同一个页面
2、不用支持IE
缺点:IE8一下不支持
history示例

window.location.pathname
console.log(window.location.pathname)
默认就是/
注:
如果仅仅似是修改pathname
体验会变差 每次点都要刷新 重新渲染
所以浏览器出了一个新的API 叫做history api
默认number存在=/ 所以要if判断
<a class="link" href="/1">go to 1</a>
---------------------------------------------------------------
const allA = document.querySelectorAll("a.link");
//上面这个方法拿到的allA是不能直接map的
//用这个方法取遍历
for (let a of allA) {
a.addEventListener("click", e => {
e.preventDefault();
//得到a的href
const href = a.getAttribute("href");
//history 第一个参数似乎个对象 第二个参数是title 第三个是链接
//这里就是你之前是刷新去href我现在不让你去了,我用下面这个方法去,路径就会在不刷新页面的情况下变更
window.history.pushState(null, `page ${href}`, href);//改变URL但不刷新页面
// 通知 自己定义一个函数来代替之前的监听事件
onStateChange(href);
});
function onStateChange() {
console.log("state 变了");
route(app);
}
不用onStateChange也可以,当window.history.pushState(null, `page ${href}`, href);之后我们页面已经跳转了
但是之前的JS已经执行完了 但是它内容还没有渲染上来 所以必须再 route(app); 再次把内容渲染上去
for (let a of allA) {
a.addEventListener("click", e => {
e.preventDefault();
const href = a.getAttribute("href");
window.history.pushState(null, `page ${href}`, href);
route(app);
});
}
memory 模式
hash 和 history 把数据都放在链接上
memory不一样 存在localStorage
memory:用一个对象存储你的东西,用到了localstorage 把路径存到用户看不到的地方
本示例 存到了xxx里面
window.localStorage.getItem("xxx")
就去看xxx是多少即可
把你要跳的东西存到xxx中
好处 适合非浏览器 app 里面的路由 他没有路径的呀
只能用memory模式
前面两种都是把路径存到URL里面 一个是哈希一个是路径
memory不用URL 放哪里不关心 前端可能放localstorage
移动端可能放在本地数据库
缺点就是没有URL,只对单机有效
你进入4了再把URL发给别人 那人家就获取到的是初始状态 1
另外两种URL记录信息 分享的时候 页面显示几 别人看到就是几