今日碰壁之路由hash和history 有壁就破,不破不立。

今天工作时候遇到了路由问题,挣扎了一早上时间,于是决定研究路由,不破不立。

首先植入一个概念,vue-router是前端路由,前端路由不是vue-router。

所以,什么是前端路由?

前端路由是服务器用来描述页面路径的,也就是你地址栏的里url和文件的关系,也就是映射关系,更加程序化的来描述,就是对象里key和value的关系。

用vue router来举列子。你的地址里path名为home ,你的component就得引用 home.vue 

{
  path: '/home',
  name: 'home',
  component: () => import(/* webpackChunkName: "LSD.bighome" */ '../views/home.vue'),
}, 

路由会做什么?

      大致有下面的三个场景。

        1.浏览器地址变化时,刷新页面(组件替换或更新)

        2.点击浏览器后退和更新,网页内容也变化

        3.刷新浏览器,浏览器加载当前的url对应的内容

hash和history 模式区别小览

      hash: 通过hashchange 事件监听hash值的变化,值变了,网页内容改变

       history :利用history API实现url地址改变,网页内容改变;

      认识hash

  • hash指的是地址中#号以及后面的字符,也称为散列值。hash也称作锚点,本身是用来做页面跳转定位的。如http://127.0.0.1:5500/hash.html#niubi,这里的#niubi就是hash;
  • 散列值是不会随请求发送到服务器端的,所以改变hash,不会重新加载页面;
  • 监听 window 的 hashchange 事件,当散列值改变时,可以通过 location.hash 来获取和设置hash值;

hash模式值散列值进行了变化,真正的路径并没有变,hash 变化时,页面并不会刷新,

只是因为了监听了hashchange的事件,对页面进行了替换。而内容替换这种行为完全由前端控制,因此这种模式使用这种模式的应用也被称为 SPA 应用。

大家观察,vue router的默认模式。就是hash模式。

大家可以用下面的代码去体验hash

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实现hash</title>
</head>

<body>
    <h3>Old Hash: <span id="oldhash"></span></h3>
    <h3>new Hash: <span id="newhash"></span></h3>
    <button id="btn">Goto gjh</button>
    <script>
        const btn = document.getElementById('btn')
        // 给按钮绑定事件
        btn.addEventListener('click', () => {
            location.href = '/#/gjh-home'
        })
        // hash 监听
        window.addEventListener('hashchange', (hashevent) => {
            const oldhash = document.getElementById('oldhash')
            const newhash = document.getElementById('newhash')
            // 将新、旧路径赋值到页面对应位置
            oldhash.innerText = hashevent.oldURL
            newhash.innerText = hashevent.newURL
            console.log(hashevent)
        })
        // hash 监听
        // window.onhashchange = (hashevent) => {
        //     const oldhash = document.getElementById('oldhash')
        //     const newhash = document.getElementById('newhash')
        //     // 将新、旧路径赋值到页面对应位置
        //     oldhash.innerText = hashevent.oldURL
        //     newhash.innerText = hashevent.newURL
        //     console.log(hashevent)
        // }
    </script>
</body>
</html>

认识history 

history 和hash最大区别就是,保存了当前窗口访问过的所有页面网址,你可以用history.length 来获取当前的窗口一共访问了几个页面。

也就说,在点击前进和后退按钮时,就是在已经访问过的页面里面去找,因此不会刷新页面。

当改变时 也只是改变页面的路径。

而 history 模式是通过模拟路径变化来切换路由。

我在下图里共添加了15个路径 用history.length就可以访问历史保存页面的数量

这时我们点击后退按钮回到以前访问过的页面时,页面通常是从浏览器缓存之中加载,而不是重新要求服务器发送新的网页。

体验history

History.pushState() 该方法用于在历史中添加一条记录。pushState()方法不会触发页面刷新,只是导致 History 对象发生变化,地址栏会有变化。

popstat() 每当 history 对象出现变化时,就会触发 popstate 事件。

可以用下面的代码 去体验下区别

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>体验history</title>
</head>
<body>
    <h3>new path: <span id="newpath"></span></h3>
    <button id="btn">Goto gjh</button>
    <script>
      const btn = document.getElementById('btn')
      const newpath = document.getElementById('newpath')
      let num= 0
      btn.addEventListener('click', () => {
        const state = {name: 'gjh'}
        // 不会触发 onpopstate 钩子
        history.pushState(state, '','gjh'+ (num++))
        // =============  路由切换逻辑 =============== //
        newpath.innerText = location.pathname
      })
      // 监听 path 变化,浏览器前进、后退触发
      window.onpopstate = (event) => {
        console.log(event)
        newpath.innerText = location.pathname
      } 
    </script>
  </body>
</html>

但是history 致命的缺点就是当改变页面地址后,强制刷新浏览器时,(如果后端没有做准备的话)会报错,因为刷新是拿当前地址去请求服务器的,如果服务器中没有相应的响应,会出现 404 页面。

hash和history 模式区别大览

hashhistory
能够兼容到IE8能兼容到IE10
实际的url之前使用哈希字符,这部分url不会发送到服务器,不需要在服务器层面上进行任何处理每访问一个页面都需要服务器进行路由匹配生成 html 文件再发送响应给浏览器,消耗服务器大量资源
刷新不会存在 404 问题浏览器直接访问嵌套路由时,会报 404 问题。
不需要服务器任何配置需要在服务器配置一个回调路由
有 # 号无#号

推荐hash的理由

  不需要服务端的配置,它就是通过散列值 就是#号后面path 变化了,进行内容替换

更不需要向网络发起任何的请求

vue-router 默认使用的就是hash

hash弊端

hash 不利于 SEO(搜索引擎优化)。

白屏时间问题。浏览器需要等待 JavaScript 文件加载完成之后渲染 HTML 文档内容,用户等待时间稍长。

  • 33
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值