Vue笔记十二——了解vue-router点进来!!!

vue-router详解

认识路由

  • 目前前端流行的三大框架,都有自己的路由实现:
    • Angular的ngRouter
    • React的ReactRouter
    • Vue的vue-router
  • 当然,我们的重点是vue-router
    • vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。
    • 我们可以访问其官网进行学习。
  • vue-router是基于路由组件的。
    • 路由用于设定访问路径,将路径和组件映射起来。
    • 在vue-router的单页面应用中,页面的路径的改变就是组件的切换。

什么是路由?

  • 说起路由你想起了什么?

    • 路由是一个网络工程里面的术语。
    • 路由routing,就是通过互联的网络把信息从源地址传输到目的地址的活动。
  • 没听懂?

    • 在生活中,我们有没有听过路由的概念呢?当然了,路由器嘛。
    • 路由器是做什么的?你有想过么?
    • 路由器提供了两种机制:路由转送
      • 路由是决定数据包从来源目的地的路径。
      • 转送将输入端的数据传递转移到合适的输出端
    • 路由中有一个非常重要的概念叫路由表
      • 路由表本质上是一个映射表,决定了数据包的指向。

后端路由阶段

  • 早期的网站开发整个HTML页面是由服务器来渲染的。
    • 服务器直接生产渲染好对应的HTML页面,返回给客户端进行展示。
  • 但是,一个网站,这么多页面,服务器如何处理呢?
    • 一个页面有自己对应的网址,也就是URL。
    • URL会发送到服务器,服务器会通过正则表达式对该URL进行匹配,并且最后交给一个Controller进行处理。
    • Controller进行各种处理,最终生成HTML或者数据,返回给前端。
    • 这就完成了一个IO操作。
  • 上面这种操作,就是后端路由。
    • 当我们页面中需要请求不同的路径内容时,交给服务器来进行处理,服务器渲染好整个页面,并且将页面返回给客户端。
    • 这种情况下渲染好的页面,不需要单独加载任何的js和css,可以直接交给浏览器显示,这样也有利于SEO优化。
  • 后端路由的缺点
    • 一种情况是整个页面的模块由后端人员编写和维护。
    • 另一种情况是前端开发人员如果要开发页面,需要通过PHP和Java等语言来编写页面代码。
    • 而且通常情况下HTML代码和数据以及对应的逻辑会混在一起,编写和维护都是非常糟糕的事情。

前后端分离阶段

  • 随着Ajax的出现,有了前后端分离的开发模式。
  • 后端只提供API来返回数据,前端通过Ajax获取数据,并且可以通过JavaScript将数据渲染到页面中。
  • 这样做最大的优点就是前后端责任的清晰后端专注于数据上前端专注于交互和可视化上
  • 并且当移动端(IOS/Android)出现后,后端不需要进行任何处理,依然使用之前的一套API即可。
  • 目前很多网站依然采用这种开发模式。

单页面富应(SPA页面)用阶段:

  • 其实SPA最主要的特点就是在前后端分离的基础上加了一层前端路由
  • 也就是前端来维护一套路由规则。

前端路由的核心是什么呢?

  • 改变URL,但是页面不进行整体的刷新。
  • 如何实现呢?

url的hash和HTML5的history

  • 正常情况下,我们改变URL会进行页面整体的刷新,会重新请求一些资源:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PqBAoD6y-1610382678369)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/1.gif)]

  • 使用location.hash更改url不会,而会从前端路由的映射中找到响应的组件,将其渲染:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fb1Mv9kk-1610382678372)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/2.gif)]

URL的hash也就是锚点(#),本质上是改变window.loaction的href属性。

我们可以通过直接赋值location.hash来改变href,但是页面不发生刷新。

  • HTML5的history模式:pushState和replaceState:
    • 简单来讲pushState会将历史记录压入一个栈中,调用history.back()可以返回上一个url。
    • replaceState()会替换掉,无法返回。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-klM2ezbJ-1610382678374)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/3.gif)]

  • HTML5的history模式:go

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QEmTRvJt-1610382678376)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/4.jpg)]

还有一个history.forward()等价于go(1)

扫描二维码关注公众号,回复: 12478754 查看本文章

vue-router基本使用

  • 因为我们已经学习了webpack,后续开发中,我们主要是通过工程化的方式进行开发的。

    • 所以在后续,我们直接使用npm来安装路由即可。

    • 步骤一:安装vue-router:

 npm install vue-router --save
  • 步骤二:在模块化工程中使用它(因为是一个插件,所以可以通过Vue.use()来安装路由功能)

    • 第一步:导入路由对象,并且调用Vue.use(VueRouter)
  • 第二布:创建路由实例,并且传入路由映射配置

    • 第三步:在Vue实例挂载创建的路由实例
  • 使用vue-router步骤:

    • 第一步:创建路由组件。
    • 第二步:配置路由映射:组件和路径映射关系。
    • 第三步:使用路由:通过<router-link><router-view>

演示

  • 首先,我们创建完项目,将其中默认文件都删除掉,我们再演示router的使用,此时页面应该为空白:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yNiRoeRN-1610382678377)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/5.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ovZB5vtU-1610382678379)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/6.jpg)]

  • 我们创建项目时,选择了vue-router,就相当于帮我们安装了vue-router这个插件了,我们就不需要通过npm再次安装。
  • 在src下,创建一个router的文件夹,里面放关于的路由的配置,在router文件夹下,创建index.js文件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E0vjvJzF-1610382678380)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/7.jpg)]

  • 在该index.js文件中完成相关配置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hoBO4lyQ-1610382678382)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/8.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MY8J488v-1610382678383)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/9.jpg)]

  • 创建对应组件:Home组件与About组件。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lSCbuVAZ-1610382678387)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/10.jpg)]

  • 配置映射关系:使组件与路径映射

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mVWorOxV-1610382678388)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/11.jpg)]

  • 通过<router-link><router-view>使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SiCdU7sr-1610382678389)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/12.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MEKMSKu0-1610382678389)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/13.gif)]

  • <router-link>:该标签是一个vue-router中已经内置的组件,他会被渲染成一个<a>标签。
  • <router-view>:该标签会根据当前的路径,动态渲染出不同的组件。
    • 网页的其他内容,比如顶部的标题/导航,或者底部的一些版权信息等会和<router-view>处于同一个等级
    • 在路由切换时,切换的是<router-view>挂载的组件,其他内容不会发生改变。

路由的默认路径

  • 我们这里有一个不太好的实现:
    • 默认情况下,进入网站的首页,我们希望<router-view>渲染首页的内容。
    • 但是我们的实现中,默认没有显示首页组件,必须让用户点击才可以。
  • 如果可以让路径默认跳到首页,并且<router-view>渲染首页组件呢?
    • 非常简单,我们只需要配置多一个映射就可以了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DhEBGtIi-1610382678390)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/14.jpg)]

  • 配置解析:
    • 我们在routes中有配置了一个映射。
    • path配置的是根路径:/
    • redirect是重定向,也就是我们将根路径重定向到/home的路径下,这样就可以得到我们想要的结果了。

HTML5的history模式

  • 我们前面说过改变路径的方式有两种:
    • URL的hash
    • HTML5的history
    • 默认情况下,路径的改变使用的是URL的hash
  • 如果希望使用HTML5的history模式,非常简单,进行如下配置即可:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jprdRmPH-1610382678391)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/15.jpg)]

  • 效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NWIQDKhW-1610382678391)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/16.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TEf426p4-1610382678392)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/17.jpg)]

router-link标签补充

  • 在前面的<router-link>中,我们只使用了一个属性:to,用于指定跳转的路径。

  • <router-link> 还有一些其他属性

    • tag:tag可以执行<router-link>之后渲染成什么组件,比如下面的代码会被渲染成一个button元素,而不是a标签。

      <router-link to='/home' tag='button'></router-link>
      
    • replace:replace不会留下history记录,所以指定replace的情况下,后退键返回不能返回到上一个页面中。

    • active-class:当<router-link>对应的路由匹配成功时,会自动给当前元素设置一个router-link-active的class设置active-class可以修改默认的名称。

      • 在进行高亮显示的导航菜单或者底部tabbar时,会使用到该类。
      • 但是通常不会修改类的属性,会直接使用默认的router-link-active即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uKUG2Ah1-1610382678393)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/18.jpg)]

通过代码修改路由

<template>
  <div id="app">
    <!-- <router-link to="/home">首页</router-link>
    <router-link to="/about">关于</router-link> -->
    <button @click="clickHome">首页</button>
    <button @click="clickAbout">关于</button>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
     
     
  name: 'App',
  methods: {
     
     
    clickHome() {
     
     
      // 通过代码的方式修改路由 vue-router
      this.$router.push('/home');
      //或this.$router.replace()
    },
    clickAbout() {
     
     
      this.$router.push('/about');
    }
  }
}
</script>

<style>

</style>

  • 有时候,页面的跳转可能需要执行JavaScript代码,这个时候,就可以使用第二种跳转方式了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r55XpABB-1610382678393)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/19.jpg)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3dfTSQVk-1610382678394)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/20.gif)]

动态路由

  • 我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。
  • 那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e1Zxwy5O-1610382678395)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/21.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eT2YqNPW-1610382678396)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/22.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wR4WFoNQ-1610382678397)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/23.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1RucQ28T-1610382678397)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/24.jpg)]

路由懒加载(官方)

  • 当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

  • 结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

  • 官方在说什么呢?

    • 首先,我们知道路由中通常会定义很多不同的页面。
    • 这个页面最后被打包在那里呢?一般情况下,是放在一个js文件中。
    • 但是,页面这么多放在一个js文件中,必然会造成这个页面非常大。
    • 如果我们一次性从服务器请求下来这个页面,可能需要花费一定的时间,甚至用户的电脑上还会出现短暂的空白。
    • 如何避免这种情况呢?使用路由的懒加载就可以了。
  • 路由懒加载做了什么

    • 路由懒加载的主要作用就是将路由对应的组件打包成一个个的js代码块。
    • 只有在这个路由被访问到的时候,才加载对应的组件。
  • 首先,可以将异步组件定义为返回一个 Promise 的工厂函数 (该函数返回的 Promise 应该 resolve 组件本身):

const Foo = () => Promise.resolve({
    
     /* 组件定义对象 */ })
  • 第二,在 Webpack 2 中,我们可以使用动态 import语法来定义代码分块点 (split point):
import('./Foo.vue') // 返回 Promise
  • 注意

    • 如果您使用的是 Babel,你将需要添加 syntax-dynamic-import 插件,才能使 Babel 可以正确地解析语法。
  • 结合这两者,这就是如何定义一个能够被 Webpack 自动代码分割的异步组件。

const Foo = () => import('./Foo.vue')
  • 在路由配置中什么都不需要改变,只需要像往常一样使用 Foo
const router = new VueRouter({
    
    
  routes: [
    {
    
     path: '/foo', component: Foo }
  ]
})

把组件按组分块把组件按组分块

  • 有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。
const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
  • Webpack 会将任何一个异步模块与相同的块名称组合到相同的异步块中。

打包文件解析

  • 我们在之前的项目中运行npm run build打包文件,出现:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z7LJROuJ-1610382678398)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/25.jpg)]

懒加载使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kwtAbLEl-1610382678414)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/26.jpg)]

  • 使用懒加载方式导入文件,再次打包文件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hLWbgGAE-1610382678415)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/27.jpg)]

vue-router嵌套路由

认识嵌套路由

  • 嵌套路由是一个很常见的功能
    • 比如在home页面中,我们希望通过home/news和home/message访问一些内容。
    • 一个路径映射一个组件,访问这两个路径也会分别渲染两个组件。

嵌套路由的使用

  • 首先我们创建两个组件HomeNews和HomeMessage:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PwalPyXg-1610382678418)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/28.jpg)]

  • 在index.js中懒加载导入这两个组件,并在Home组件下使用children属性将两个组件配置好。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JXjGraH8-1610382678421)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/29.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UDqBvRv7-1610382678422)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/30.jpg)]

  • 在Home组件中设置<router-link><router-view>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DyfjpmTB-1610382678424)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/31.jpg)]

  • 效果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gVd0QdTb-1610382678426)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/32.gif)]

vue-router参数传递

  • 当我们从一个页面跳转到另一个页面的时候,很有可能需要给我们传递一些参数

  • 传递参数主要有两种方式:params和query

  • params类型(上方动态路由):

    • 配置路由格式:/router/:id
    • 传递的方式:在path后面跟上对应的值
    • 传递后形成的路径:/router/123,/router/abc
  • query的类型

    • 配置路由格式:/router,也就是普通配置
    • 传递的方式:对象中使用query的key: value作为传递方式
    • 传递后形成的路径:/router?id=123,/router?id=abc

演示query类型:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ORiB6Rqn-1610382678428)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/33.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YMxJEwwV-1610382678430)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/34.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Km8pO4Fn-1610382678432)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/35.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ktNuIBk1-1610382678433)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/36.jpg)]

  • 一般大量数据由query传递。

vue-router导航守卫

为什么要使用导航守卫?

  • 我们来考虑一个需求:在一个SPA应用中,如何改变网页的标题呢?

    • 网页标题是通过<title>来显示的,但是SPA只有一个固定的HTML,切换不同的页面时,标题并不会改变。
    • 但是我们可以通过JavaScript来修改<title>的内容,window.document.title = '新的标题'
    • 那么在Vue项目中,在哪里修改?什么时候修改比较合适呢?
  • 普通的修改方式:

    • 我们比较容易想到的修改标题的位置时每一个路由对应的组件.vue文件中。
    • 通过mounted声明周期函数,执行对应的代码进行修改即可。
    • 但是当页面比较多时,这种方式不容易维护(因为需要在多个页面执行类似的代码)
  • 有没有更好的方法呢?使用导航守卫即可。

  • 什么是导航守卫?

    • vue-router提供的导航守卫只要用来监听路由的进入和离开的。
    • vue-router提供了beforeEach和afterEach的钩子函数,它们会在路由即将改变前和改变后触发。

导航守卫使用

  • 我们可以利用beforeEach来完成标题的修改。
    • 首先,我们可以在钩子当中定义一些标题,可以利用meta来定义。
    • 其次,利用导航守卫,修改我们的标题。
  • 导航钩子的三个参数解析
    • to:即将要进入的目标的路由对象。
    • form:当前导航即将要离开的路由对象。
    • next:调用该方法后,才能进入下一个钩子。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pj4elJXr-1610382678435)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/37.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TSIxgfM7-1610382678437)(/Users/mac/Desktop/前端学习笔记/vue/vue笔记十二/38.jpg)]

  • 补充一:如果是后置钩子,也就是afterEach,不需要主动调用next()函数。
  • 补充二:上面我们使用的导航守卫,被称之为全局守卫
    • 路由独享的守卫。
    • 组件内的守卫。

回顾

Vue笔记一——Vue安装与体验
Vue笔记二——Vue声明周期与模板语法
Vue笔记三——计算属性(computed)
Vue笔记四——事件监听的使用
Vue笔记五——条件判断与循环遍历
Vue笔记六——书籍购物车案例
Vue笔记七——v-model表单输入绑定详细介绍
Vue笔记八——关于组件不可不知的知识!
Vue笔记九——slot插槽的使用
Vue笔记十——webpack敲重点!!!(详解)
Vue笔记十一——Vue CLI相关

猜你喜欢

转载自blog.csdn.net/weixin_46351593/article/details/112504610