Vue Router - 前端路由实现思路(三种模式:hash、history、memory)
1.路由是什么搞清楚这几个概念:路由分发路由表默认路由如果没有#n,就给一个默认值number = number || 1;404 路由 / 保底路由如果用户输入了错误路径,就给一个404页面,保证用户总是能够看到一个页面嵌套路由1.1 路由器如果家里有1个即以上的人要上网,就需要一个路由器上网路由1.用户上网连接路由器,路由器看你想连哪里,就会把信号包发给相应的地方(百度、抖音、腾讯等)2.分发
·
1.路由是什么
- 搞清楚这几个概念:
- 路由
- 分发
- 路由表
- 默认路由
如果没有#n,就给一个默认值
number = number || 1;
- 404 路由 / 保底路由
如果用户输入了错误路径,就给一个404页面,保证用户总是能够看到一个页面 - 嵌套路由
1.1 路由器
- 如果家里有1个即以上的人要上网,就需要一个路由器
- 上网路由
1.用户上网连接路由器,路由器看你想连哪里,就会把信号包发给相应的地方(百度、抖音、腾讯等)
2.分发:分别发送到各个地方
3.路由就是分发请求,路由器就是分发请求的东西
4.路由都是一对多的(一个用户可以发送多个请求到不同地方) - 总结:分发请求的对象就是路由
1.2 前端路由
- 路由表:一个存储到各个目的地的最佳路径的表
1.路由根据路由表来传送
2.所有框架实现路由都有路由表 - 前端路由
根据用户提供的url是:http://127.0.0.1/#1
、#2、#3、#4,分别展示DIV1、DIV2、DIV3、DIV4界面 - hash:hash就是url中#及其后面的内容
1.可通过:window.location.hash
获得url中的 #xxx
2.修改页面hash:<a href="#1">go to 1</a>
通过a标签可以改变hash的值
3.监听hash变化:当URL的片段标识符更改时,将触发hashchange事
—— 跟在#符号后面的URL部分,包括#符号
——window.addEventListener("hashchange",()=>{})
- 代码优化逻辑
1.默认路由:如果没有给任何路径,则给默认值
——number = number || 1
2.404:给了错误路径,给一个404路由
//最简单的路由实现
//HTML中
<a href="#2">go to 2</a>
<div class="app"></div>
<div style="display=none" id="div1">1</div>
<div style="display=none" id="div1">2</div>
<div style="display=none" id="div1">3</div>
<div style="display=none" id="div1">4</div>
<div style="display=none" id="div404">404</div>
//JS中
const number = window.loacation.hash.substr(1)
number = number || 1 //默认路由:number不存在就取1
const div = document.querySelector(`#div${number}`)
const app = document.querySelector(`#app`)
div.display = 'block'
app.appendChild(div)
window.addEventListener("hashchange",()=>{
//重新获取hash,将新的div放到div#app中显示
})
1.3 路由表
- hash和div的关系是可以自定义的
比如:hash给了1,可以找 div1或者 divone
const div1 = document.createElement("div")
div1.innerHTML = "1"
//234同理
const routeTable = {
// 表驱动编程,这样写了HTML里面就不需要div了
"1": div1,
"2": div2,
"3": div3,
"4": div4
};
function route(){//渲染路由
let number = window.location.hash.substr(1)
const app = document.querySelector(`#app`)
//根据表来寻找对应的div
let div = routeTable[number.toString()];
//获取界面、渲染界面代码省略
app.appendChild(div)
}
1.4 嵌套路由
- 如果#1界面里面还有几块子界面:#1/1、#1/2、#1/3
1.那么就不是在app里面路由,而是在div1里面做路由
2.所以要给 route 函数一个参数container,也就是要在哪里路由,容器是哪一个
3.这样就不需要 app 这个参数了,而是直接container代替
4.后面再调用route的时候就需要传参:app - 和之前的路由一样,给一个hash表:route1Table
- 后面的思路
1.把1/1分割成两个部分:[1,1]
2.第一个1就用第一层路由去渲染,就得到了div1
3.第二个1就用第二个路由去渲染,就在div1里面得到了div11 - 路由可以再分层
function route(container){//渲染路由
let number = window.location.hash.substr(1)
//把1/1分割成两个部分:[1,1],分割前后两个数字,根据两个路由表来寻找对应的div
let div = routeTable[number.toString()];
container.innerHTML = ''
container.appendChild(div)
}
router(div1) //router(app)
2.路由的三种模式
- hash 模式:代码
任何情况都可以用hash做前端路由
缺点:SEO不友好,服务器收不到hash
——浏览器是不会把#后面的内容发给服务器的
——无论访问baidu.com/#xxx
都默认访问baidu.com/
,永远展示默认路由
谷歌有专门针对hash的SEO,但没什么用 - history 模式:代码
使用场景:后端将所有前端路由都渲染同一页面
用户不管请求什么都到同一个页面(不能是404页面)
——baidu.com/xxxx
不论/后面输入什么都到首页
缺点:IE8以下不支持 - memory 模式:代码
既不用hash,也不用history,用对象来存储 - 三种模式的区别
1.前面两种模式都是路径存在url上面(前者是存的hash,后者是路径)
2.memory是单机路由,不可分享
2.1 hash模式
- 从hash中得到number
let number = window.location.hash.substr(1);
有#号,要去掉 - 路径:/#1
2.2 history 模式
- codesandbox网页就支持这个模式
不论用户后面输入什么乱码(没有路由的情况),都是首页 - 区别
1.从pathname得到number
let number = window.location.pathname
——获得:/1
2.routeTable中的key要变成"/1"
3.a标签中的href由 #n 变成 /n - 路径:/1
不需要#
- 目前的体验:每次点击都要重新渲染页面,很慢
- 解决:history API
//点击a标签,阻止默认事件,跳转到页面
a.addEventListener("click",e=>{
e.preventDefault()
const href = a.getAtrribute("href")
window.history.pushState(null, `page ${href}`, href);
onStateChange(href) //通知state改变,并传参数
})
function onStateChange(){
route(app)
}
2.3 hash模式和history模式对比
- 使用条件不用
1.hash模式在任何条件都可以使用,但SEO不友好,服务器收不到hash
2.history模式:后端将所有的页面都渲染到同一个非404页面;IE8不支持 - number的获取方式不同
- a标签的点击事件不同
1.history需要阻止默认事件:刷新页面
2.得到href,然后通过window.history.pushState去相应的href,页面就会在不刷新的情况下变更 - 没有可监听的事件,需要手动通知href改变,然后调用router函数,重新渲染页面
- 默认页面不同
1.history:number默认是/,是存在的,因此要判断
2.hash:默认不存在 - 点击a标签后,默认做两件事
1.改变url默认不刷新页面
2.重新路由
2.4 memory 模式
- hash和history都有一个共同点
把所有数据存在路径后面,不论是/1还是/#1,这里的东西一变,所有的东西都改变
- memory不用这个地方,这里不改变,页面不改变
使用localstorage
- 优点
这种模式适合非浏览器
比如说app里面做路由,app里面没有路径,不是网页,就用memory模式 - 缺点:没有url
只对单机有效
页面没有链接 复制给别人只能进入初始状态
3.Vue-Router 源码
- Vue作者写的路由器
- Vue官方路由
更多推荐
已为社区贡献2条内容
所有评论(0)