记录--啊?Vue是有三种路由模式的?

这篇具有很好参考价值的文章主要介绍了记录--啊?Vue是有三种路由模式的?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

记录--啊?Vue是有三种路由模式的?

众所周知,vue路由模式常见的有 historyhash 模式,但其实还有一种方式-abstract模式(了解一哈~)

别急,本文我们将重点逐步了解: 路由 + 几种路由模式 + 使用场景 + 思考 + freestyle


路由概念

路由的本质就是一种对应关系,根据不同的URL请求,返回对应不同的资源。那么url地址和真实的资源之间就有一种对应的关系,就是路由。


路由模式由来

对于 Vue 这类渐进式前端开发框架,为了构建 SPA(单页面应用),需要引入前端路由系统,这也就是 Vue-Router 存在的意义。而前端路由的核心,就在于 —— 改变视图的同时不会向后端发出请求

为了达到这一目的,就产生了我们的 —— 路由模式


三种路由模式详解


hash模式

示例: www.ikun.com/#/kun,hash 的值为 #/kun。

概述:

地址栏 URL 中有 # 符号,后面就是 hash 值的变化(此 hash 不是密码学里的散列运算)。特点是:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端没有影响,改变后面的 hash 值,它不会向服务器发出请求,因此也就不会 刷新页面/重新加载页面

每次 hash 值发生改变的时候,会触发 hashchange 事件。因此我们可以通过监听该事件,来知道 hash 值发生了哪些变化。

window.addEventListener('hashchange', ()=>{
    // 通过 location.hash 获取到最新的 hash 值
    console.log(location.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>hash路由</title>
</head>
<body>
​
  <ul>
    <!-- 通过标签导航  声明式导航 -->
    <!-- location.href='#/home' js方式进行导航切换 编程式导航 -->
    <li><a href="#/home">首页</a></li>
    <li><a href="#/about">关于</a></li>
  </ul>
​
  <div id="routerView"></div>
​
  <script>
    const routerRender = () => {
      // 每次都置空hash
      let html = ''
      // 根据地址栏hash值的不同返回对应的资源
      try {
        // 如果hash值为空就给一个home
        let hash = location.hash || '#/home'
        html = component[hash.slice(2)]()
      } catch (error) {
        html = `<div>404</div>`
      }
      // 渲染到页面上
      document.getElementById('routerView').innerHTML = html
    }
​
    const component = {
      home() {
        return `<div>home页面</div>`
      },
      about() {
        return '<div>关于页面</div>'
      }
    }
​
    window.onload = function () {
      routerRender()
    }
​
    // 事件,监听地址栏中的hash值变化,实现回退
    window.addEventListener('hashchange', routerRender)
      
  </script>
</body>
</html>

优缺点:

优点:hash模式兼容性、安全性很强,刷新浏览器,页面还会存在

缺点:地址栏不优雅,有#存在,不利于seo,记忆困难

注意:

hash 模式既可以通过声明式导航,也可以通过编程式导航,上面的案例展示的是声明式导航。而下面将要讲到的 history 模式只能通过编程式导航实现,因为 history 是 js 对象。


history模式

示例: www.ikun.com/kun,地址栏中没有#,路由地址跟正常的url一样

概述:

history —— 利用了 HTML5 History API 为浏览器的全局 history 对象增加的 pushState()replaceState() 方法,可以对浏览器历史记录栈进行修改。(新增特性,所以浏览器需考虑IE9以及以下的版本带来的问题)。当地址栏的history状态发生变化时 切换了router-view渲染的组件 来"欺骗"用户 到达切换新网页的效果,需要后端配合

History 还包括back、forward、go三个方法,对应浏览器的前进,后退,跳转操作。就是浏览器左上角的前进、后退等按钮进行的操作。

history.go(-2);//后退两次
history.go(2);//前进两次
history.back(); //后退
hsitory.forward(); //前进

只要历史栈有信息发生改变的话,window对象中提供的 popstate 事件就会监听到历史栈的改变,就会触发该事件。

history.pushState({},title,url); // 向历史记录中追加一条记录
history.replaceState({},title,url); // 替换当前页在历史记录中的信息。
​
window.addEventListener('popstate', function(e) {
  console.log(e)
})

使用:

<!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>history模式</title>
</head>
​
<body>
  <ul>
    <li><a href="/home">首页</a></li>
    <li><a href="/about">关于</a></li>
  </ul>
​
  <div id="routerView"></div>
​
  <script>
    const component = {
      home() {
        return `<div>home页面</div>`
      },
      about() {
        return '<div>关于页面</div>'
      }
    }
​
    const routerRender = pathname => {
      let html = ''
      try {
        html = component[pathname]()
      } catch (error) {
        html = `<div>404</div>`
      }
      document.getElementById('routerView').innerHTML = html
    }
​
    // history模式,它的路由导航,只能通过js来完成 , history它是js对象
    // 给链接添加点击事件
    document.querySelectorAll('a').forEach(node => {
      node.addEventListener('click', function (evt) {
        // 阻止a标签的默认跳转行为
        evt.preventDefault()
        // 跳转到指定的地址,能回退
        // history.pushState
        // 跳转到指定持址,不能回退
        // history.replaceState
        history.pushState({}, null, this.href)
        // 渲染
        routerRender(this.href.match(//(\w+)$/)[1])
      })
    })
​
    // 在网页加载完毕后立刻执行的操作,即当 HTML 文档加载完毕后,立刻渲染 home 中的标签
    window.onload = () => {
      routerRender('home')
    }
​
    // 回退
    window.addEventListener('popstate', function () {
      routerRender(location.pathname.slice(1))
    })
​
  </script>
</body>
</html>

优缺点:

缺点:history模式,兼容性较差,刷新页面,页面会404,需要服务器端配置支持

优点:地址栏更优雅,方便记忆,有利于有seo


刷新页面出现404原因以及解决:

原因:

因为vue项目中路由hash模式改为了history模式,由于hash模式时url带的#号后面是哈希值不会作为url的一部分发送给服务器,而history模式下当刷新页面之后浏览器会直接去请求服务器,而服务器没有这个路由,于是就出现404

因为我们的应用是单页客户端应用,当使用 history 模式时,URL 就像正常的 url,可以直接访问www.ikun.com/kun/love,但是因为 vue-router 设置的路径不是真实存在的路径,所以刷新就会返回404错误

解决方法(后端配合,这里讲的是nginx配置):

在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。也就是在服务端修改404错误页面的配置路径,让其指向到index.html

方法一:

    location /{
        root   /data/nginx/html;
        index  index.html index.htm;
        if (!-e $request_filename) {
            rewrite ^/(.*) /index.html last;
            break;
        }
    }

方法二: (vue.js官方教程里提到的https://router.vuejs.org/zh-cn/essentials/history-mode.html)

  server {
        listen       8888;#默认端口是80,如果端口没被占用可以不用修改
        server_name  localhost;
        root        E:/vue/my_project/dist;#vue项目的打包后的dist
        location / {
            try_files $uri $uri/ @router;#需要指向下面的@router否则会出现vue的路由在nginx中刷新出现404
            index  index.html index.htm;
        }
        #对应上面的@router,主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件
        #因此需要rewrite到index.html中,然后交给路由在处理请求资源
        location @router {
            rewrite ^.*$ /index.html last;
        }
        #.......其他部分省略
  }

abstract模式

abstract模式----适用于所有JavaScript环境,例如服务器端使用Node.js。如果没有浏览器API,路由器将自动被强制进入此模式。

abstract 是一种与浏览器分离的路由模式,本身是用来在不支持浏览器API的环境中,充当fallback,而不论是hash还是history模式都会对浏览器上的url产生作用。

利用abstract这种与浏览器分离的路由模式,我们可以在已存在的路由页面中内嵌其他的路由页面,而保持在浏览器当中依旧显示当前页面的路由path。


使用场景


history --- 颜值性(强迫症患者推荐,更友好的URL格式、SEO支持)

一般场景下,hash 和 history 都可以,除非你更在意颜值,# 符号夹杂在 URL 里看起来确实有些不太美丽。我们可以用路由的 history 模式,充分利用 history.pushState API 来完成URL 跳转而无须重新加载页面。如果需要更好的SEO支持,并且愿意进行服务器端配置,history 模式是很好的选择

调用 history.pushState() 相比于直接修改 hash,还存在以下优势

1、pushState() 设置的新 URL 可以是与当前 URL 同源的任意 URL;而 hash 只可修改 #后面的部分,因此只能设置与当前 URL 同文档的 URL;

2、pushState() 设置的新 URL 可以与当前 URL 一模一样,这样也会把记录添加到栈中;而 hash设置的新值必须与原来不一样才会触发动作将记录添加到栈中;

3、pushState() 通过 stateObject 参数可以添加任意类型的数据到记录中;而 hash 只可添加短字符串;

4、pushState() 可额外设置 title 属性供后续使用。

hash ---- 安全兼容,不需要后端协助

SPA 虽然在浏览器里游刃有余,但真要通过 URL 向后端发起 HTTP 请求时,两者的差异就来了。尤其在用户手动输入 URL 后回车,或者刷新(重启)浏览器的时候

hash 模式下,仅 hash 符号之前的内容会被包含在请求中,如 www.ikun.com ,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误

abstract模式 ---- 特殊场景

abstract模式----适用于所有JavaScript环境(浏览器端和服务端),例如服务器端使用Node.js。

像上文说的,可以利用abstract这种与浏览器分离的路由模式,在已存在的路由页面中内嵌其他的路由页面,而保持在浏览器当中依旧显示当前页面的路由path。


小结


选择使用 hash 模式还是 history 模式,主要取决于你的具体需求和项目要求。如果你的应用不需要考虑SEO,并且不涉及服务器端的重定向和处理,Hash模式是一种简单且易于使用的选择。如果你需要更友好的URL格式、更好的SEO支持,并且愿意进行服务器端配置,那么history 模式是更好的选择。

结合自身例子,对于一般形式的 Web 开发场景,个人比较习惯用用 history 模式,只需在后端(Apache 或 Nginx)进行简单的路由配置,同时搭配前端路由的 404 页面支持。

本文转载于:

https://juejin.cn/post/7297035708429484066

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 记录--啊?Vue是有三种路由模式的?文章来源地址https://www.toymoban.com/news/detail-746110.html

到了这里,关于记录--啊?Vue是有三种路由模式的?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Solidity中函数有三种装饰器

    Solidity中函数有三种装饰器,分别是pure、view和payable。使用装饰器可以轻松改变函数的行为。 pure 装饰器 表示在函数中没有修改任何函数以外的变量,包括状态变量,只是单纯地进行了一个数值计算。函数的执行并不会消耗任何Gas,因为函数执行使用的是本地节点的CPU,所以

    2024年02月13日
    浏览(29)
  • PHP的curl有三种Post请求数据的方式

    今天要讲的HTTP请求头的Content-Type字段,就是在curl发送post请求的时候需要指定以何种方式来请求数据,常用的有3类: 1、form-data 。就是 multipart/form-data 使用表单的方式来发送数据 是curl采用的默认发送方式。请求数组类型的格式。 Content-Type: multipart/form-data 2、x-www-form-urlenco

    2024年02月11日
    浏览(50)
  • 使用maven打包时如何跳过test,有三种方式

    方式一 针对spring项目: 针对springboot:  方式二(通用 ): 方式三(通用): mvn package -DskipTests=true -DskipTests=true,不执行测试用例,但编译测试用例类生成相应的class文件至 target/test-classes 下。   mvn package -Dmaven.test.skip=true -Dmaven.test.skip=true,不执行测试用例,也不编译测试

    2024年02月13日
    浏览(29)
  • 标记垃圾,有三种色彩:四千长文带你深入了解三色标记算法

    🔭 嗨,您好 👋 我是 vnjohn,在互联网企业担任 Java 开发,CSDN 优质创作者 📖 推荐专栏:Spring、MySQL、Nacos、Java,后续其他专栏会持续优化更新迭代 🌲文章所在专栏:JVM 🤔 我当前正在学习微服务领域、云原生领域、消息中间件等架构、原理知识 💬 向我询问任何您想要的

    2024年02月13日
    浏览(30)
  • 荣耀magicbook重装系统后,指纹不能录入的情况,有三种解决办法,完美解决问题。

    有些小伙伴用了很多年的荣耀的笔记本还没坏,但是用着很卡,就想着重装windows系统,系统是重装完了,但是发现指纹录入不上了,就像下面这样,手指放在感应器上也不管用。 本人电脑是2018年买的,已经是过了保修期了,咨询了客服,检测是不需要自己掏钱的,但是如果

    2024年02月02日
    浏览(28)
  • vue三种路由守卫详解

    查看本专栏目录 关于作者 还是大剑师兰特 :曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,echarts等技术开发,欢迎加底部微信,一起交流。 热门推荐 内容链接

    2024年02月20日
    浏览(29)
  • Verilog的三种描述方式(结构化描述、数据流描述、行为级描述对电路功能的描述有三种方式:结构化描述、数据流描述、行为级描述

    Verilog的三种描述方式(结构化描述、数据流描述、行为级描述对电路功能的描述有三种方式:结构化描述、数据流描述、行为级描述。三种描述方式抽象级别不同,各有优缺点,相辅相成,需要配合使用。 目录 一、结构化描述 1、概念 2、特点 3、示例 真值表: 电路抽象:

    2024年02月04日
    浏览(55)
  • vue路由传参的三种方式

    目录 1.动态路由传参 2.params传参 3.query传参         使用“路径参数”使用冒号  :  标记。当匹配到一个路由时,参数值会被设置到  this.$route.params ,也可以使用props来接收   params  传参(不显示参数)也可分为 声明式 和 编程式 两种方式,与方式一不同的是,这里是通过

    2024年02月11日
    浏览(31)
  • 视频字幕如何提取出来?教大家三种方法

    在观看视频时,字幕是帮助我们更好理解内容的重要元素。有时候,我们可能想要提取视频中的字幕,以便于后续翻译、编辑或者与他人分享。提取视频字幕可以让我们更方便地进行语言学习、创作和传播。现如今,有许多工具和技术可以帮助我们轻松地从视频文件中提取字

    2024年02月06日
    浏览(46)
  • 怎么用手机压缩图片?教给大家三种手机压缩图片方法

    如何使用手机把图片的内存进行压缩呢?大家在使用照片的时候,如果照片的内存太大,不仅会占用手机的内存,也会影响一些网站上传图片的操作,因为图片内存太大很多都是上传不了的,为了解决这一问题我们可以将图片进行压缩。今天给大家分享三种手机就能压缩图片

    2024年02月08日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包