一、前言

  前端路由是什么?如果你之前从事的是后端的工作,或者虽然有接触前端,但是并没有使用到单页面应用的话,这个概念对你来说还是会很陌生的。那么,为什么会在单页面应用中存在这么一个概念,以及,前端路由与我们后端的路由有什么异同呢。本章,我们就来简单介绍下前端路由的概念,以及如何在 Vue 中使用 Vue Router 来实现我们的前端路由。

  学习系列目录地址:https://www.cnblogs.com/danvic712/p/9549100.html

  仓储地址:https://github.com/Lanesra712/VueTrial/blob/master/chapter02-bronze/router/sample.html

二、干货合集

  在传统的多页面应用中,网站的每一个 URL 地址都是对应于服务器磁盘上的一个实际物理文件。例如,当我们访问 https://www.yousite.com/index.html 这个网址的时候,服务器会自动把我们的请求对应到当前站点路径下面的 index.html 文件,然后再给予响应,将这个文件返回给浏览器。当我们跳转到别的页面上时,毫无疑问则会再重复一遍上面的过程。

  但是在单页面应用中,整个项目中只会存在一个 html 文件,当用户切换页面时,只是通过对这个唯一的 html 文件进行动态重写,从而达到响应用户的请求。也就是说,从切换页面这个角度上说,应用只是在第一次打开时请求了服务器(非服务端渲染的单页应用)。

  因为访问的页面是并不真实存在的,所以如何正确的在一个 html 文件中展现出用户想要访问的信息就成为单页面应用需要考虑的问题,而对于这一路由问题的解决方案,为了与我们后端传统意义上的路由进行区别,就将此称为前端路由。

  1、前端路由的实现方式

  目前的前端路由的实现方式主要是通过 hash 路由匹配或者是采用 html5 中的 history api 这两种,也就是说,不管是 hash 路由还是使用 history 路由模式,其实都是基于浏览器自身的特性。

  hash 路由:hash 这个概念,可能听起来有些陌生,不过,其实我们在之前的前端开发中,其实是有所接触的。例如,在某些情况下,我们需要定位页面上的某些位置,就像下面的例子中展现的那样,我想要通过点击不同的按钮就跳转到指定的位置,这里我们使用的锚点定位其实就是 hash。

  1. <div id="content">
  2. <div class="btn-container">
  3. <a class="btn" href="#image1">图片1</a>
  4. <a class="btn" href="#image2">图片2</a>
  5. </div>
  6. <img src="./xxx/xxx.jpg" id="image1">
  7. <img src="./xxx/xxx.jpg" id="image2">
  8. </div>

  hash 路由的本质是浏览器 location 对象中的 hash 属性,它会记录链接地址中 '#' 后面的内容(e.g.:#part1)。因此,我们可以通过监听 window.onhashchange 事件获取到跳转前后访问的地址,从而实现地址切换的目的。

  history 路由:在之前的 html 版本中,我们可以通过 history.back(), history.forward()和 history.go() 方法来完成在用户历史记录中向后和向前的跳转。而 history 路由则是使用了 html5 中新增的 pushState 事件和 replaceState() 事件。

   通过这两个新增的 API,就可以实现无刷新的更改地址栏链接,配合 AJAX 就可以做到整个页面的无刷新跳转,具体实现的原理大家可以看看这篇文章 =》https://www.renfei.org/blog/html5-introduction-3-history-api.html

  在 Vue 中,Vue Router 是官方提供的路由管理器。它和 Vue.js 的核心深度集成,因此,不管是采用 hash 的方式还是使用 history api 实现我们的前端路由都有很好的支持,所以这里我们采用 Vue Router 这一组件来实现我们的前端路由。

  2、路由实现

  首先我们需要将 Vue Router 添加引用到我们的项目中,这里我还是采用直接引用 js 文件的方式为我们的示例代码添加前端路由支持。

  在 Vue 中使用 Vue Router 构建单页面应用,我们只需要将组件 (components) 映射到定义的路由 (routes) 规则中,然后告诉 Vue Router 在哪里渲染它们,并将这个路由配置挂载到 Vue 实例节点上即可。

  在 Vue Router 中,我们使用 router-link 标签来渲染链接,当然,默认生成的是 a 标签,如果你想要将路由信息生成别的 html 标签,则可以使用 tag 属性指明需要生成的标签类型。

  1. <!-- 默认渲染成 a 标签 -->
  2. <router-link to="/home">主页</router-link>
  3.  
  4. <!-- 渲染成 button 标签 -->
  5. <router-link to="/home" tag="button">主页</router-link>

  可以看到,当我们指定 tag 属性为 button 后,页面渲染后的的标签就变成了 button 按钮。同样的,它还是会监听点击,触发导航。

  同时,从上图可以看出,当前的链接地址为 #/home,也就是说,通过 router-link 生成的标签,当页面地址与对应的路由规则匹配成功后,将自动设置 class 属性值为 .router-link-active。当然,我们也可以通过指定 active-class 属性或者在构造 VueRouter 对象时使用 linkActiveClass 来自定义链接激活时使用的 CSS 类名。

  1. <!-- 使用属性来设定自定义激活类名 -->
  2. <router-link to="/home" active-class="aaaa">主页</router-link>
  3.  
  4. <!-- 在构造对象时设定全局默认类名 -->
  5. const router = new VueRouter({
  6. routes: [],
  7. linkActiveClass: 'aaaaa'
  8. })

  当路由表构建完成后,对于指向路由表中的链接,需要在页面上找一个地方去显示已经渲染完成后的组件,这时,我们就需要使用 router-view 标签去告诉程序,我们需要将渲染后的组件显示在当前位置。

  在下面的示例代码中,模拟了 Vue 中路由的使用,当访问 #/home 时会进行加载 home 组件,而当链接跳转到 #/account 时则会加载 account 组件。同时,我们可以发现,在 account 组件中又包含了两个子路由,通过点击 account 组件中的子路由地址,从而加载对应的 login 组件和 register 组件。

  1. <script src="../../lib/vue.js"></script>
  2. <script src="../../lib/vue-router.js"></script>
  3. <style>
  4. .container {
  5. background-color: aquamarine;
  6. margin-top: 20px;
  7. width: 740px;
  8. height: 300px;
  9. }
  10. </style>
  11.  
  12. <div id="app">
  13.  
  14. <!-- 通过 router-link 标签来生成导航链接 -->
  15. <router-link to="/home">主页</router-link>
  16. <router-link to="/account">账户</router-link>
  17.  
  18. <div class="container">
  19. <!-- 将选中的路由渲染到 router-view 下-->
  20. <router-view></router-view>
  21. </div>
  22. </div>
  23.  
  24. <template id="tmpl">
  25. <div>
  26. <h3> account page </h3>
  27.  
  28. <!-- 生成嵌套子路由地址 -->
  29. <router-link to="/account/login">登录</router-link>
  30. <router-link to="/account/register">注册</router-link>
  31.  
  32. <!-- 生成嵌套子路由渲染节点 -->
  33. <router-view></router-view>
  34. </div>
  35. </template>
  36.  
  37. <script>
  38. // 1、定义路由跳转的组件模板
  39. const home = {
  40. template: '<div> home page </div>'
  41. }
  42.  
  43. const account = {
  44. template: '#tmpl'
  45. }
  46.  
  47. const login = {
  48. template: '<div> login page</div>'
  49. }
  50.  
  51. const register = {
  52. template: '<div> register page</div>'
  53. }
  54.  
  55. // 2、定义路由信息
  56. const routes = [{
  57. path: '/',
  58. redirect: '/home'
  59. },
  60. {
  61. path: '/home',
  62. component: home
  63. },
  64. {
  65. path: '/account',
  66. component: account,
  67. children: [{
  68. path: 'login',
  69. component: login
  70. },
  71. {
  72. path: 'register',
  73. component: register
  74. }
  75. ]
  76. }
  77. ]
  78.  
  79. const router = new VueRouter({
  80. //mode: 'history', //使用 history 模式还是 hash 路由模式
  81. routes
  82. })
  83.  
  84. // 3、挂载到当前 Vue 实例上
  85. const vm = new Vue({
  86. el: '#app',
  87. data: {},
  88. methods: {},
  89. router: router
  90. });
  91. </script>

  在上面的代码中,也使用到了嵌套路由和路由的重定向。通过使用路由重定向,我们可以将用户访问网站的根目录 / 时进行重定向到 /home ,而嵌套路由则可以将 URL 中各段动态路径也按某种结构对应到实际嵌套的各层组件。

  例如,这里的 login 组件和 register 组件,它们都是位于 account 组件中的,因此,在构建 url 时,我们应该将该地址位于 /account url 后面,从而更好地表达这种关系。所以这里,我们在 account 组件中又添加了一个 router-view 标签,用来渲染出嵌套的组件内容。同时,通过在定义 routes 时在参数中使用 children 属性,从而达到配置嵌套路由信息的目的。

  PS:以 / 开头的嵌套路径会被当作根路径,而我们的 login 组件和 register 组件都是包含在 account 中,所以这里直接定义 path 参数即可。

三、总结

  这一章主要是介绍了如何使用 Vue Router 在 Vue 中构建我们的前端路由。在实际开发中,对于一个路径,可能会对应到多个组件,这时,如何将多个组件绑定到一个路径下,就是我们需要解决的问题。另外,在实际使用中我们会遇到路由传参,可能会因为 hash 路由不漂亮,从而准备采用 history 路由,对于这些需求的实现,将放在下一章中进行学习。

四、参考

  1、从头开始学习vue-router

  2、单页面应用路由的两种实现方式

  3、你需要知道的单页面路由实现原理

  4、面试官: 你了解前端路由吗?

  5、前端路由实现原理(history)

[Vue 牛刀小试]:第十二章 - 使用 Vue Router 实现 Vue 中的前端路由控制的更多相关文章

  1. [Vue 牛刀小试]:第十七章 - 优化 Vue CLI 3 构建的前端项目模板(1)- 基础项目模板介绍

    一.前言 在上一章中,我们开始通过 Vue CLI 去搭建属于自己的前端 Vue 项目模板,就像我们 .NET 程序员在使用 asp.net core 时一样,我们更多的会在框架基础上按照自己的开发习 ...

  2. [Vue 牛刀小试]:第十三章 - Vue Router 基础使用再探(命名路由、命名视图、路由传参)

    一.前言 在上一章的学习中,我们简单介绍了前端路由的概念,以及如何在 Vue 中通过使用 Vue Router 来实现我们的前端路由.但是在实际使用中,我们经常会遇到路由传参.或者一个页面是由多个组件 ...

  3. PRML读书会第十二章 Continuous Latent Variables(PCA,Principal Component Analysis,PPCA,核PCA,Autoencoder,非线性流形)

    主讲人 戴玮 (新浪微博: @戴玮_CASIA) Wilbur_中博(1954123) 20:00:49 我今天讲PRML的第十二章,连续隐变量.既然有连续隐变量,一定也有离散隐变量,那么离散隐变量是 ...

  4. <构建之法>第十一章、十二章有感

    十一章:软件设计与实现 工作时要懂得平衡进度和质量.我一直有一个困扰:像我们团队这次做 男神女神配 社区交友网,我负责主页的设计及内容模块,有个队友负责网站的注册和登录模块,有个队友负责搜索模块,有个 ...

  5. sql 入门经典(第五版) Ryan Stephens 学习笔记 (第六,七,八,九,十章,十一章,十二章)

    第六章: 管理数据库事务 事务 是 由第五章 数据操作语言完成的  DML ,是对数据库锁做的一个操作或者修改. 所有事务都有开始和结束 事务可以被保存和撤销 如果事务在中途失败,事务中的任何部分都不 ...

  6. 《Linux命令行与shell脚本编程大全》 第二十二章 学习笔记

    第二十二章:使用其他shell 什么是dash shell Debian的dash shell是ash shell的直系后代,ash shell是Unix系统上原来地Bourne shell的简化版本 ...

  7. 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高

    第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...

  8. [CSAPP笔记][第十二章并发编程]

    第十二章 并发编程 如果逻辑控制流在时间上是重叠,那么它们就是并发的(concurrent).这种常见的现象称为并发(concurrency). 硬件异常处理程序,进程和Unix信号处理程序都是大家熟 ...

  9. perl5 第十二章 Perl5中的引用/指针

    第十二章 Perl5中的引用/指针 by flamephoenix 一.引用简介二.使用引用三.使用反斜线(\)操作符四.引用和数组五.多维数组六.子程序的引用  子程序模板七.数组与子程序八.文件句 ...

随机推荐

  1. [转]Go基础之锁的初识

    当我们的程序就一个线程的时候是不需要用到锁的,但是通常我们实际的代码不会是单个线程的,所有这个时候就需要用到锁了,那么关于锁的使用场景主要涉及到哪些呢? 当我们多个线程在读相同的数据的时候则是需要加锁 ...

  2. [NPM] Set default values for package.json using npm set

    Npm by default uses global values when initializing a new package.json file. Learn how to set your o ...

  3. 【iOS】KVC 与 KVO

    一.KVC与KVO *"KVC":key value Coding(键值编码) *目的:间接的改动或获取对象的属性,减少程序(类与类)之间的耦合度. *"KVO" ...

  4. CellularAutomation(细胞自己主动机)

    CellularAutomation(细胞自己主动机) 细胞自己主动机(英语:Cellular automaton).又称格状自己主动机.元胞自己主动机,是一种离散模型,在可算性理论.数学及理论生物学 ...

  5. 整理对Spark SQL的理解

    Catalyst Catalyst是与Spark解耦的一个独立库,是一个impl-free的运行计划的生成和优化框架. 眼下与Spark Core还是耦合的.对此user邮件组里有人对此提出疑问,见m ...

  6. Comparable 和 Comparator的理解

    对Comparable 的解释 Comparable是一个排序接口 此接口给实现类提供了一个排序的方法,此接口有且只有一个方法 public int compareTo(T o); compareTo ...

  7. 当年用httpclient时踩过的那些坑

    一.前言 httpclient是java开发中最常用的工具之一,通常大家会使用其中比较基础的api去调用远程.长期开发爬虫,会接触httpclient不常用的api,同时会遇到各式各样的坑,本文将总结 ...

  8. 格式转换至yuv422转 yuv420

    //pYUV为422,yuv为420 /*ok! * brief:pyuv is yuv422sp srcIn, and yuv is yuv420p desOut  */ int YUV422To4 ...

  9. word2vec学习 spark版

    参考资料: http://ir.dlut.edu.cn/NewsShow.aspx?ID=291 http://www.douban.com/note/298095260/ http://machin ...

  10. sanic官方文档解析之Response和Cookie

    1,Sanic的返回的响应体 使用Sanic中的response模块去创建响应对象 返回文本response.text文本(直接字符串就ok) 返回html文件,直接response.html文件(类 ...