前端路由的两种模式-----Hash模式 ,History模式

5,003 阅读4分钟

⭐ 前言

一、前端路由是什么?

前端路由是在保证只有一个HTML页面的情况下,通过对每个视图展示形式匹配一个特殊的url来实现所谓的切换效果。不会重新向服务端发送请求,也不会跳转页面。无论是刷新、前进、还是后退,都可以通过特殊url实现。


1-1 SPA

单页web应用(single page web application,SPA)

它只有一个HTML页面。它的核心是更新视图不需要重新请求页面。 所谓的页面跳转,多个页面之间的切换是利用JS动态的变换HTML的内容,加载的时候不是加载整个页面,而是某个指定的容器中的内容。

举栗子:阿呆有一个水壶,刚开始装的是牛奶,过一会儿装的是果汁,再过一会又是开水。可水壶还是一个水壶!

SPA的缺点:

1、无法记住用户的操作记录,

2、且只有一个url,对SEO不友好。


🍓前端路由的重要的作用

1、可以在改变url的时候不会向服务器发送请求。

2、可以监听到url的改变。

二、正式开始吧

2-1 hash模式

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/city',
      name: 'City',
      component: City
    },
    {
      path: '/detail/:id',
      name: 'Detail',
      component: Detail
    },
    {
      path: '/search',
      name: 'Search',
      component: Search
    }
  ]
})

--hash模式下的url

 http://localhost:8080/#/
 http://localhost:8080/#/detail/1

这里的 hash 就是指 url 后的 # 号以及后面的字符。比如说 "www.baidu.com/#hashhash" ,其中 "#hashhash" 就是我们期望的 hash 值。 hash 值的变化不会导致浏览器像服务器发送请求,而且hash 的改变会触发 hashChange 事件浏览器的前进后退也能对其进行控制,所以在 H5 的 history 模式出现之前,基本都是使用 hash 模式来实现前端路由。

2-2 history模式

以下是我个人项目中的页面跳转 history模式

const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/login',
      name: 'login',
      component: ()=>import('./views/Login.vue'),
    },
    {
      path: '/register',
      name: 'register',
      component: ()=>import('./views/Register.vue'),
    },
    {
      path: '/information',
      name: 'information',
      component: ()=>import('./views/Information.vue'),
    },
    {
      path: '/chat',
      name: 'chat',
      component: ()=>import('./views/ChatView.vue'),
    }
  ]
});

login

concacts

在 HTML5 之前,浏览器就已经有了 history 对象。但在早期的 history 中只能用于多页面的跳转。

重要)在 HTML5 的规范中,history 新增了以下几个 API:

history.pushState(); // 添加新的状态到历史状态栈

history.replaceState(); // 用新的状态代替当前状态

history.state // 返回当前状态对象

history.pushState() 和 history.replaceState() 的区别?

history.pushState() 在保留现有历史记录的同时,将 url 加入到历史记录中。 history.replaceState() 会将历史记录中的当前页面历史替换为 url。 由于 history.pushState() 和 history.replaceState() 可以改变 url 同时,不会刷新页面,所以在 HTML5 中的 histroy 具备了实现前端路由的能力。

但需要注意的是,history 在修改 url 后,虽然页面并不会刷新,但我们在手动刷新,或通过 url 直接进入应用的时候, 服务端是无法识别这个 url 的。

因为我们是单页应用,只有一个 html 文件,服务端在处理其他路径的 url 的时候,就会出现404的情况。 所以,如果要应用 history 模式,需要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回单页应用的 html 文件。

popstate

在history模式中与hash模式的hashchange对应的是popState。popstate是在浏览器回退前进或者js的 back() go() forward()方法的时候才会触发。

<button @click="$router.go(-1)">返回</button> //返回上一级

<button @click="$router.back()">返回</button> //返回上一级

<button @click="$router.forward()">返回</button> //切换到下一级

那么大家就会有疑问——如果只能通过js的api才可以触发popState, 那pushStatereplaceState怎么被popState“注意”到?

答案:可以通过a标签改变url,检测到url发生改变。 大致大代码如下:

⭐ 总结:

hash模式和history模式对比

1、hash 模式相比于 history 模式的优点:

  1. 兼容性更好,可以兼容到IE8
  2. 无需服务端配合处理非单页的url地址

2、hash 模式相比于 history 模式的缺点:

  1. 看起来更丑。
  2. 会导致锚点功能失效。
  3. 相同 hash 值不会触发动作将记录加入到历史栈中,而 pushState 则可以。