lhlGitHub / trisome

前端大厂进攻学习资料库
21 stars 1 forks source link

vue-router 中常用的 hash 和 history 路由模式实现原理 #21

Open lhlGitHub opened 2 years ago

CheeseLeee commented 2 years ago

i only know simple how do this , as change historyState and listenr hashChange

chenzhengli commented 2 years ago

1.hash是通过监听hash值的变化,触发hashchange方法,来匹配对应的组件 2.history是通过监听浏览器路由的变化popState方法来匹配对应的组件

jiayechao commented 2 years ago

hash路由

hash(#xx)的改变并不会引起页面的重载,但是会在历史栈加入。通过监听hashchange,动态渲染对应的组件。

history路由

history就是History对象,通过pushState事件修改路由地址,但此时页面是不会刷新的 页面监听popstate,当history发生改变时(注意:pushState并不能触发这个事件。只有当点击后退,或者调用back,go等才会触发),动态渲染对应的组件。

history的缺点就是在强制重载页面时,因为后端服务并没有对应的页面,会出现404的错误。所以需要后端协助此时返回index页面

d2120848471 commented 2 years ago

vue-router 默认 hash 模式(#)是通过锚点来实现的,实际只是我们页面上的位置切换并不会引起我们的刷新后端请求, 单改变#号后面的东西只是滚动到了我们对应的位置,并且每次滚动都会被记录,我们可以可以通过后退到达上一个位置,总的来说就是根据#后面的路径来渲染我们dom树上不同的数据,会触发hashchange事件

<!DOCTYPE html>

Document A页面 B页面

history API 是 H5 提供的新特性,允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求(将url替换并且不刷新页面)。 主要就是这几个api history.replaceState({}, null, '/b') // 替换路由 history.pushState({}, null, '/a') // 路由压栈 替换当前地址 被替换地址进入访问历史 history.back() // 返回 history.forward() // 前进 history.go(-2) // 后退2次

<!DOCTYPE html>

history A页面 B页面
Moannas commented 2 years ago

1、hash:使用URL hash值作为路由,默认包含#,hash是URL中的锚点,代表网页中的一个位置,,单单改变#后面的部分,浏览器只会加载相应位置的内容,不会重新加载页面,通过锚点值改变

2、history:window对象,HTML5新增的API,history模式则会将URL修改的和正常请求后端的URL一样,如果后端没有配置对应的路由则会返回404错误,所以需要和后端配合在服务器端增加一个覆盖所有情况的候选资源,比如匹配不到返回同一个index.html页面; 14年后,因为HTML5标准发布。多了两个 API,pushState 和 replaceState,通过这两个 API 可以改变 url 地址且不会发送请求。同时还有popstate 事件。通过这些就能用另一种方式来实现前端路由了,但原理都是跟 hash 实现相同的。用了 HTML5 的实现,单页路由的 url 就不会多出一个#,变得更加美观。但因为没有 # 号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。

loringray commented 2 years ago
  1. hash 模式: hash (“#”)符号的作用是加在 URL 中指示网页中的位置;# 符号本身以及它后面的字符称之为 hash, 可以通过 window.location.hash 属性读取 特点: (1)、hash 虽然出现在 URL 中,但是不会在 HTTP 请求中,对服务端无用,因此 hash 不会重新加载页面。 (2)、可以给 hash 的改变添加监听事件 window.addEventListener('hashchange', func, false) 每一次改变 hash-window.location.hash,都会在浏览器的访问历史上增加一个记录。

  2. history 模式 history-History API 是浏览器历史记录栈的接口,通过 go()、back()、forward()等方法,可以读取浏览器历史记录栈的信息。 从 HTML5 开始,提供了两个新的方法, pushState()、replaceState() 让我们修改浏览器历史记录栈。 window.history.pushState(stateObject, title, url) window.history.replaceState(stateObject, title, url) 当用户主动触发(点击前进/后退按钮)或者调用上述 go() 等方法,就会触发 popState 事件。 上面两个方法共同点:当调用他们修改浏览器历史记录栈后,虽然当前 URL 改变了,但浏览器不会刷新页面;浏览器历史记录可以看作一个栈,用户每点开一个新页面相当于入栈,用户点击后退相当于出栈。当需要使用到历史记录功能时候,就可以考虑设计使用栈数据结构来实现。