ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
>[success] # 分清前端路由的 history 和 hash 路由 1. 两种方式均为客户端路由的实现方式:当路径法发生变化,不会向服务器发送请求,使用js监视路径的变化 根据不同的地址渲染不同的内容,如果需要服务器端的内容会发送Ajax请求来获取 1.1. Hash模式url中带#号 #号后边内容为路由地址 url带井号或者问号 1.2. History 模式正常url模式 2. 原理区别: 2.1. `Hash`模式是基于锚点,以及`onhashchange`事件。通过锚点值作为路由地址,路由变化后 触发`onhashchange`事件 2.2. `History` 模式是基于HTML5中的`History API` 有兼容问题 `history.pushState()` IE10以后才支持 `history.replaceState()` 不会向服务器发送请求,仅改变浏览器地址栏中的地址,并且将地址记录到历史记录中,api 如下 * `replaceState`:替换原来的路径 * `pushState`:使用新的路径; * `popState`:路径的回退; * `go`:向前或向后改变路径; * `forward`:向前改变路径; * `back`:向后改变路径; 3. 虽然`History` 模式不会向后台发送请求,但是注意一点,用户如果刷新页面或者重新请求该地址 会像后台服务器发起请求,此时没有对应连接对应的页面会产生查找不到页面,如果使用history模式 需要`后台配合 ` 4. 总结: 4.1. `Hash 模式`: URL中#后面的内容作为路径地址,仅改变# 后面的内容则不会向服 务器请求这个地址,但会记录到访问历史中,监听hashchange事件,url改变会触发该事件 ,根据当前路由地址找到对应组件重新渲染 4.2. `History 模式 `:通过`history.pushState()`方法改变地址栏,仅改变地址栏并将其记录到访问历史中,并不会跳转到指定路径即不会向服务器发送请求 监听 `popstate` 事件,可以记录改变后的地址,调用`pushState和replaceState`时不会触发该事件,后退或前进历史页面时才会触发 根据当前路由地址找到对应组件重新渲染 >[danger] ##### history简单案例 ~~~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" /> <title>Document</title> <div id="app"> <a href="/home" class="router">home</a> <a href="/index" class="router">about</a> <div class="content">Default</div> </div> </head> <body> <script> class VueRouter { constructor(options, identifier) { this.options = options // 注册路由列表 this.routerMap = {} this.identifier = identifier this.initRouterMap() this.initEvent() this.clickHandler() } initRouterMap() { const contentEl = document.querySelector('.content') for (let key in this.options) { this.routerMap[key] = () => (contentEl.innerHTML = this.options[key]) } } // 当点击 a 标签时候 取消默认跳转行为 // 将前端路由储存 并且渲染对应路由对应节点 clickHandler() { const els = document.getElementsByClassName(this.identifier) ;[...els].forEach((el) => { el.addEventListener('click', (e) => { // 阻止默认事件 e.preventDefault() const href = el.getAttribute('href') history.pushState({}, '', href) this.routerMap[href]() }) }) } initEvent() { // 当触发如用户点击浏览器的回退按钮(或者在Javascript代码中调用history.back()或者history.forward()方法 触发 window.addEventListener('popstate', () => { this.routerMap[location.pathname]() }) } } const urlMap = { '/home': `<p>home</p>`, '/index': `<p>index<p>`, } const vueRouter = new VueRouter(urlMap, 'router') </script> </body> </html> ~~~ >[danger] ##### 使用 hash 模式 ~~~ <!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"> <title>Document</title> </head> <body> <div id="app"> <a href="#/home">home</a> <a href="#/about">about</a> <div class="content">Default</div> </div> <script> const contentEl = document.querySelector('.content'); window.addEventListener("hashchange", () => { switch(location.hash) { case "#/home": contentEl.innerHTML = "Home"; break; case "#/about": contentEl.innerHTML = "About"; break; default: contentEl.innerHTML = "Default"; } }) </script> </body> </html> ~~~ >[danger] ##### 简单看vuerouter 使用 1. 知道上面原理后,先了解以下vueRouter 使用这里版本`4.x` * 根据上面案例首先创建一个 路由映射 形成路由和组件关系 * 可以选择具体使用`hash `形式 还是 `history `形式 * 通过一个容器可以将我们映射的内容展示出来 ~~~ import { createRouter, createWebHistory } from "vue-router"; import HomeView from "../views/HomeView.vue"; // map 形成路由和组件的关系 const routes = [ { path: "/", name: "home", component: HomeView, }, { path: "/about", name: "about", component: () => import(/* webpackChunkName: "about" */ "../views/AboutView.vue"), }, ]; // 创建了路由对象 const router = createRouter({ history: createWebHistory(process.env.BASE_URL), // hash 和 history 选择 routes, }); export default router; ~~~ * 使用时候容器 ~~~html <template> <nav> <router-link to="/">Home</router-link> | <router-link to="/about">About</router-link> </nav> <!-- 使用时候容器 --> <router-view /> </template> ~~~