文章目录

vue-router详解

# 认识路由

路由是一个网络工程里面的术语。

路由(routing)就是<mark>通过互联的网络把信息从源地址传输到目的地址的活动</mark>. — 维基百科{一个不存在的网站}

如:路由器提供了两种机制: 路由和转送.

## 路由表

<mark>路由是决定数据包从来源到目的地的路径.</mark>(转送将输入端的数据转移到合适的输出端.)

路由中有一个非常重要的概念叫 路由表 .

<mark>路由表本质上就是一个映射表, 决定了数据包的指向.</mark>

## 后端路由(渲染)阶段

<mark>注意哦:不是说路由等于渲染。</mark>

早期 的网站开发整个 HTML 页面是由 服务器 来渲染的.

(服务器直接生产渲染好对应的HTML页面, 返回给客户端进行展示.)

一个网站, 这么多页面服务器如何处理呢?

一个页面有自己对应的网址, 也就是 URL.
URL 会发送到服务器, 服务器会通过正则对该 URL 进行匹配, 并且最后交给一个 Controller 进行处理.

Controller 进行各种处理, 最终生成 HTML 或者数据, 返回给前端.
这就完成了一个 IO 操作.
上面的这种操作, 就是后端路由.

优点、缺点

  • 优点:
    当我们页面中需要请求不同的路径内容时, 交给服务器来进行处理, 服务器渲染好整个页面, 并且将页面返回给客户顿.
    这种情况下渲染好的页面, <mark>不需要单独加载任何的js和css, 可以直接交给浏览器展示, 这样也有利于SEO的优化</mark>.

  • 缺点:

    1. 一种情况是整个页面的模块由后端人员来编写和维护的.
    2. 另一种情况是前端开发人员如果要开发页面, 需要通过 PHPJava 等语言来编写页面代码.
      而且通常情况下 HTML <mark>代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情.</mark>

<mark>魔鬼的渲染</mark>

## 前端路由(渲染)阶段

前后端分离阶段

<mark>随着 Ajax 的出现, 有了前后端分离的开发模式.</mark>
<mark>后端只提供 API 来返回数据, 前端通过 Ajax 获取数据, 并且可以通过 JavaScript 将数据渲染到页面中.</mark>

优点:前后端责任的清晰,

  • 后端专注于数据上
  • 前端专注于交互和可视化上.

并且当移动端(iOS/Android)出现后, 后端不需要进行任何处理, 依然使用之前的一套API即可.
目前很多的网站依然采用这种模式开发.

<mark>前后端分离</mark>

## 单页面富应用阶段:改变URL,但是页面不进行整体的刷新

其实 SPAsingle page web application = 整个网页只有一个html页面)<mark>最主要的特点就是在前后端分离的基础上加了一层前端路由.</mark>
也就是前端来维护一套路由规则.

前端路由的核心是什么呢?
改变URL,但是页面不进行整体的刷新。

那么问题来了,
如何实现 <mark>改变页面不改变url</mark>呢?

有两种方法:

  • URL的hash
  • <mark>html5的history模式</mark>

方法一:URL的hash

URLhash 也就是锚点 (#) , 本质上是改变 window.location的href 属性.

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

方法二:HTML5的history模式

1. pushState

history接口是HTML5新增的, 它有五种模式改变URL而不刷新页面.

history.pushState()

2. replaceState

history.replaceState()

和 push 有什么区别呢?
这个 replace 是替换的意思,就是不入栈的。<mark>即,不会再history保留记录</mark>

3. go

history.go()

4. back

后退

history.back() 等价于 history.go(-1)

5. forward

向前

history.forward() 则等价于 history.go(1)

这三个接口(go、back、forward)等同于浏览器界面的前进后退。


.


## 前后端路由 - 总结 (跳到 vue-router 安装

看到这里,你可以自问自答一下,下面这个几个问题。

  1. 什么是前端渲染, 什么是后端渲染?
  2. 什么是前后端分离?
  3. 什么是前端路由, 什么是后端路由?
  4. 什么是前端渲染, 什么是后端渲染?

前端渲染:(趋势)

指的是后端返回 JSO N数据,前端利用预先写的 html 模板,循环读取 JSON 数据,拼接字符串( es6 的模板字符串特性大大减少了拼接字符串的的成本),并插入页面。

  • 好处:网络传输数据量小。
    不占用服务端运算资源(解析模板),模板在前端(很有可能仅部分在前端),改结构变交互都前端自己来了,改完自己调就行。

  • 坏处:前端耗时较多,对前端工作人员水平要求相对较高。
    前端代码较多,因为部分以前在后台处理的交互逻辑交给了前端处理。占用少部分客户端运算资源用于解析模板。

后端渲染:(过时)

前端请求,后端用后台模板引擎直接生成html,前端接受到数据之后,直接插入页面。

  • 好处:前端耗时少,即减少了首屏时间,模板统一在后端。前端(相对)省事,不占用客户端运算资源(解析模板)

  • 坏处:占用服务器资源。<mark>而且代码严重耦合</mark>

前后端分离?

前端人员和后端人员约定好接口后,前端人员彻底不用再关心业务处理是怎么回事,他只需要把界面做好就可以了,

后端人员也不用再关系前端界面是什么样的,他只需要做好业务逻辑处理即可。

服务的切离,代码管理,服务部署也都独立出来分别管理,系统的灵活性也获得了极大的提升。

注意,这不是个微服务架构,那是另外一个议题了

总结,任何系统架构设计,实际上是对组织结构在系统上进行映射,前后端分离,就是在对前端开发人员和后端开发人员的工作进行解耦,尽量减少他她们之间的交流成本,帮助他她们更能专注于自己擅长的工作。

什么是前端路由, 什么是后端路由?

  1. 什么是前端路由?
    .
    <mark>很重要的一点是页面不刷新</mark>,前端路由就是把不同路由对应不同的内容或页面的任务交给前端来做,每跳转到不同的URL都是使用前端的锚点路由. 随着(SPA)单页应用的不断普及,前后端开发分离,目前项目基本都使用前端路由,在项目使用期间页面不会重新加载。

  2. 什么是后端路由?
    .
    ​ 浏览器在地址栏中切换不同的url时,每次都向后台服务器发出请求,服务器响应请求,在后台拼接html文件传给前端显示, 返回不同的页面, 意味着浏览器会刷新页面,网速慢的话说不定屏幕全白再有新内容。后端路由的另外一个极大的问题就是 前后端不分离。
    .
    ​ 缺点:
    当项目十分庞大时,加大了服务器端的压力,同时在浏览器端不能输入制定的url路径进行指定模块的访问。
    另外一个就是如果当前网速过慢,那将会延迟页面的加载,对用户体验不是很友好。

  3. 什么时候使用前端路由?
    .
    ​ 在单页面应用,大部分页面结构不变,只改变部分内容的使用

  4. 前端路由有什么优点和缺点?
    .
    优点:
    .

    1. . 用户体验好,和后台网速没有关系,不需要每次都从服务器全部获取,快速展现给用户
    2. 可以再浏览器中输入指定想要访问的url路径地址。
    3. 实现了前后端的分离,方便开发。有很多框架都带有路由功能模块。

    缺点:

    1. 使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存
    2. 单页面无法记住之前滚动的位置,无法在前进,后退的时候记住滚动的位置

最后是几个常见误解的说明:

  1. 前后端分离是说浏览器和后端服务分离吗?
    .
    不是,前后端分离里的前端不是浏览器,指的是生成 HTML 的那个服务,它可以是一个仅仅生成 HTML 的 Web 服务器,也可以是在浏览器中通过 JS 动态生成 HTML 的 单页应用。实践中,有实力的团队往往在实现前后端分离里时,前端选用 node 服务器,后端选用 C#、Java 等(排名不分先后)

  2. 前后端分离是种技术吗?
    .
    不是,前后端分离是种架构模式,或者说是最佳实践。所谓模式就是大家这么用了觉得不错,你可以直接抄来用的固定套路。

  3. 前后端分离是最佳实践吗?
    .
    看你团队和项目的情况,如果是短平快的小项目,真的没必要。如果是面向简历开发,那绝对在任何时候都应该使用前后端分离这种架构。

# 认识vue-router

目前前端流行的三大框架, 都有自己的路由实现:

  • AngularngRouter
  • ReactReactRouter

# Vue的vue-router - 官网:https://router.vuejs.org/zh/

当然, 我们的重点是 vue-router
<mark>vue-routerVue.js 官方的路由插件,它和 vue.js 是深度集成的,适合用于构建单页面应用。</mark>

我们可以访问其官方网站对其进行学习: https://router.vuejs.org/zh/

vue-router 是基于路由和组件的
路由用于设定访问路径, 将路径和组件映射起来.
vue-router <mark>的单页面应用中, 页面的路径的改变就是组件的切换</mark>.

# 安装和使用vue-router

                 

## 步骤一: 安装vue-router

npm install vue-router --save

<mark>注意,生产时候也用的,所以不是开发依赖哦!</mark>

<mark>安装完后,多了 /src/router 文件夹</mark>

## 步骤二: 在模块化工程中使用它

<mark>(因为是一个插件, 所以可以通过 Vue.use() 来安装路由功能)</mark>

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

// 第一、二步 ,在 /src/router/index.js


// 配置路由的相关信息
import VueRouter from 'vue-router'
import Vue from 'vue'

// 1. 通过 Vue.use(插件), 安装插件
Vue.use(VueRouter)

// 2. 创建 VueRouter 对象
const routes = [
	// 未来要在这里配置很多映射关系
	// 让一个url映射一个组件
	// ....
]
const router = new VueRouter({
  // 配置路由和组件之间的响应关系
  routes
})


第三步:在 Vue 实例中挂载创建的路由实例

import Vue from 'vue'
import App from './App'
// import router from './router'
// 如果导入的是目录,会自动去找目录的 index 文件
import router from './router'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
  // router,
  render: h => h(App)
})

## 使用vue-router的步骤:

第一步: 创建路由组件

这里创建两个 一个 About.vue 另外一个 Home.vue

添加 src/components/About.vue

<template>
  <div>
    <h2>我是关于</h2>
    <p>我是关于内容,哈哈哈哈哈</p>
  </div>
</template>

<script> export default { name: 'About' } </script>

<style> </style>

添加 src/components/Home.vue

<template>
  <div>
    <h2>我是首页</h2>
    <p>我是首页内容,哈哈哈哈哈</p>
  </div>
</template>

<script> export default { name: 'Home' } </script>

<style> </style>

第二步: 配置路由映射: 组件和路径映射关系 - routes

官方 routes 讲解:https://router.vuejs.org/zh/api/#routes


修改 /src/router/index.js

// 配置路由的相关信息
import VueRouter from 'vue-router'
import Vue from 'vue'

// 导入自定义组件
import Home from '../components/Home.vue'
import About from '../components/About.vue'

// 通过 Vue.use(插件), 安装插件
Vue.use(VueRouter)

// 创建 VueRouter 对象
const routes = [
  {
    path: '/home',
    component: Home
  }, {
    path: '/about',
    component: About
  }
]
const router = new VueRouter({
  // 配置路由和组件之间的响应关系
  routes
})

// 将 router 对象传入到 Vue 实例
export default router

第三步: 使用路由: 通过 <router-link><router-view>

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

修改 src/App.vue

<template>
  <div id="app">
    <router-link to="/home">首页</router-link>
    <router-link to="/about">关于</router-link>
    <router-view></router-view>
  </div>
</template>

<script> export default { name: 'App' } </script>

<style> </style>

最终效果如下



done ~~~~

## 细节处理

路由的默认路径 : redirect

默认情况下, 进入网站的首页, 占位符 <router-view> 没有内容

我们希望 <router-view> 渲染首页的内容.

怎么办?

非常简单, 我们只需要配置多配置一个映射就可以了.

我们在 routes 中又配置了一个映射.

  • path 配置的是根路径: /
  • redirect 是重定向, 也就是我们将根路径重定向到 /home 的路径下,

这样就可以得到我们想要的结果了.

注意:<mark>下面做法是不对的,url上面的值是没有改的(正常应该改为我们希望现实的内容的 url)</mark>

HTML5 的 History 模式

我们前面说过改变路径的方式有两种:

  • URLhash
  • HTML5history

默认情况下, 路径的改变使用的 URLhash .
如果希望使用 HTML5history 模式, 非常简单, 进行如下配置即可:

router-link补充

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

<router-link> 还有一些<mark>其他属性</mark>:

  • tag : <mark>tag 可以指定 <router-link> 之后渲染成什么组件</mark>,
    如:

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

    <router-link to="/home" replace>首页</router-link>
    
  • active-class: 当 <router-link> 对应的路由匹配成功时, 会自动给当前元素设置一个 router-link-activeclass , 设置 active-class 可以修改默认的名称.
    如:

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

批量修改 link-Active-Class

class 具体的名称也可以通过 router 实例的属性进行修改

进行下图修改即可


exact-active-class (路由嵌套再讲)

类似于 active-class , 只是在精准匹配下才会出现的 class .
后面看到嵌套路由时, 我们再看下这个属性.

不用 router-link ,应该怎么做? - this.$router

vue 底层会为每个 实例添加 一个属性 this.$router , 就是用来做自定义 push 的

使用如下

<template>
  <div id="app">
    <button @click="to('/home')">首页</button>
    <button @click="to('/about')">关于</button>
    <router-view></router-view>
  </div>
</template>

<script> export default { name: 'App', methods: { to (path) { this.$router.push(path) // or replace } } } </script>

<style> </style>

注意:错误例子
你可能会想到 直接调用原生的 history.pushState

to (path) 
     history.pushState({}, {}, path)
   }

.
但是,这是允许的!
理由有两个

  • 没办法直接让 <router-view> 的内容改变
  • 原则上,不要绕过 vue 操作 浏览器

# 动态路由 - 官网:https://router.vuejs.org/zh/guide/essentials/dynamic-matching.html

<mark>在某些情况下,一个页面的 path 路径可能是不确定的</mark>

比如
我们进入用户界面时,希望是如下的路径:
/user/aaaa或/user/bbbb
除了有前面的 /user 之外,后面还跟上了 用户的 ID

这种 pathComponent 的匹配关系,我们称之为<mark>动态路由</mark>(也是路由传递数据的一种方式)。

更多:https://router.vuejs.org/zh/api/#%E8%B7%AF%E7%94%B1%E5%AF%B9%E8%B1%A1

params template 上传过来的值s

## router 和 route 的区别

官方解释:https://router.vuejs.org/zh/api/#%E8%B7%AF%E7%94%B1%E5%AF%B9%E8%B1%A1%E5%B1%9E%E6%80%A7

英文上:

  • router 路由器
  • route 航线

vue 上:

# 路由的懒加载 + 打包源码(浅析)

## 认识路由的懒加载

官方给出了解释:

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

路由懒加载做了什么?

  • 路由懒加载的主要作用就是<mark>将路由对应的组件打包成一个个的js代码块</mark>.
  • <mark>只有在这个路由被访问到的时候, 才加载对应的组件</mark>

测试:

执行指令,进行打包(构建)

npm run build 

打包结果:(多了 dist 文件夹,就可以拷给后台服务器了)
下面看目录结构

  • js 文件进行了拆分
  • 暴露 index.hml 文件,给客户引用

看 index.js

## 打包源码(浅析)(直接跳到“懒加载的使用”

上面看到了 ,打包后,js被分成了几个文件

大致能分成三种:

  • appxxxxxxxxxxxxxxxx.js - 我们制定的组件
  • manifestxxxxxxxxxxxxxxx.js - 我们制定的组件的驱动
  • vendorxxxxxxxxxxxxxxxxxx.js - 第三方组件

为了上面的 js 源码可读, 我们先 到 build/webpack.prod.conf.js 里面,在生产环境下 把 丑化插件给关了

再次编译,打开 manifestxxxxx.js 文件 (先看驱动)

明显,这个方法,是在组件加载时候做显示的

这时,我们看 appxxxxxx.js 就有点头绪了。

(上图)代码分了几部分,<mark>均是立即执行函数</mark>。

中间最大一块代码,被隐藏的那部分就是我们自己写的代码的封装

(上面)可以看到,所谓打包,就是把我们的代码以<mark>立即执行函数的形式</mark>,复制到 webpackJsonp 里面,
当我们有需要的时候,声明一下,就能被调用了!

<mark>补充:《jsonp原理详解——终于搞清楚jsonp是啥了》</mark>

## 懒加载的使用

官方教程 - https://router.vuejs.org/zh/guide/advanced/lazy-loading.html#%E8%B7%AF%E7%94%B1%E6%87%92%E5%8A%A0%E8%BD%BD

之前,讲了路由懒加载是什么,还有前提知识(vue的分包)

下面讲 懒加载怎么用

懒加载的方式

现在都用第三种方法

我们修改之前的代码 src/router/index.js

// 配置路由的相关信息
import VueRouter from 'vue-router'
import Vue from 'vue'

// 导入自定义组件
// import Home from '../components/Home.vue'
// import About from '../components/About.vue'
// import User from '../components/User.vue'

// 通过 Vue.use(插件), 安装插件
Vue.use(VueRouter)

// 创建 VueRouter 对象
const routes = [
  {
    path: '/',
    redirect: '/home'
  }, {
    path: '/home',
    component: () => import('../components/Home.vue')
  }, {
    path: '/about',
    component: () => import('../components/About.vue')
  }, {
    path: '/user/:username',
    component: () => import('../components/User.vue')
  }
]
const router = new VueRouter({
  // 配置路由和组件之间的响应关系
  routes,
  mode: 'history',
  linkActiveClass: 'active'
})

// 将 router 对象传入到 Vue 实例
export default router

路由懒加载的效果

# 路由嵌套

官方教程:

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

路径和组件的关系如下:

实现嵌套路由有两个步骤:

  • 创建对应的子组件, 并且在路由映射中配置对应的子路由.

  • 在组件内部使用 < router-view> 标签.

## 嵌套路由实现

src/router/index.js

// 配置路由的相关信息
import VueRouter from 'vue-router'
import Vue from 'vue'

// 导入自定义组件
// import Home from '../components/Home.vue'
// import About from '../components/About.vue'
// import User from '../components/User.vue'

// 通过 Vue.use(插件), 安装插件
Vue.use(VueRouter)

// 创建 VueRouter 对象
const routes = [
  {
    path: '/',
    redirect: '/home'
  }, {
    path: '/home',
    component: () => import('../components/Home.vue'),
    children: [
      {
        path: '/home',
        redirect: '/home/news'
      },
      {
        // 注意,这里不加斜杠'/'
        path: 'news',
        component: () => import('../components/HomeNews.vue')
      },
      {
        path: 'message',
        component: () => import('../components/HomeMessage.vue')
      }
    ]
  }, {
    path: '/about',
    component: () => import('../components/About.vue')
  }, {
    path: '/user/:username',
    component: () => import('../components/User.vue')
  }
]
const router = new VueRouter({
  // 配置路由和组件之间的响应关系
  routes,
  mode: 'history',
  linkActiveClass: 'active'
})

// 将 router 对象传入到 Vue 实例
export default router

添加两个 组件
src/component/HomeMessage.vue

<template>
  <div>
    <p>消息</p>
  </div>
</template>

<script> export default { name: 'Message' } </script>

<style> </style>

src/component/HomeNews

<template>
  <div>
    <ul>
      <li v-for="(n,i) in news" :key='i'>{{ n }}</li>
    </ul>
  </div>
</template>

<script> export default { name: 'News', data () { return { news: [ 'Fantastic Granite Chips', 'Fantastic Granite Chips', 'Fantastic Granite Chips', 'Fantastic Granite Chips' ] } } } </script>

<style></style>

在父组件内指定添加的内容的位置

<template>
  <div>
    <h2>我是首页</h2>
    <p>我是首页内容,哈哈哈哈哈</p>
    <router-link to="/home/news">新闻</router-link>
    <router-link to="/home/message">消息</router-link>
    <router-view></router-view>
  </div>
</template>

<script> export default { name: 'Home' } </script>

<style> </style>

# 传递参数

## 传递参数的方式

传递参数主要有两种类型: paramsquery

params的类型:

<mark>前面也用过了</mark>
配置路由格式: /router/:id
传递的方式: 在 path 后面跟上对应的值
传递后形成的路径: /router/123, /router/abc

query的类型:


修改 src/router/index.js


修改 src/components/User.vue

<template>
  <div>
    <h2>{{username}}</h2>
    <h2>我是用户</h2>
    <p>用户,嘿嘿嘿~</p>
    <router-link :to="profile">详情</router-link>
    <router-view></router-view>
  </div>
</template>

<script> export default { name: 'User', computed: { username () { console.log(this) return this.$route.params.username }, profile () { return { path: `/user/${this.username}/profile`, query: { age: 18, gender: 'female', height: 180 } } } } } </script>

<style> </style>

添加 src/components/UserProfile.vue

<template>
  <div>
    <h3>age:{{$route.query.age}}</h3>
    <h3>gender:{{$route.query.gender}}</h3>
    <h3>height:{{$route.query.height}}</h3>
  </div>
</template>

<script> export default { name: 'Profile' } </script>

<style> </style>

补充:URL的组成


## 传递方式总结

传递参数方式一: <router-link>

传递参数方式二: JavaScript代码

获取参数

官方解释:https://router.vuejs.org/zh/api/#%E8%B7%AF%E7%94%B1%E5%AF%B9%E8%B1%A1%E5%B1%9E%E6%80%A7

获取参数通过 $route 对象获取的。

补充 or 回顾

# 导航守卫

官方文档: 导航守卫

## 什么是导航守卫?

vue-router 提供的导航守卫,<mark>主要用来监听监听路由的 进入离开 的.</mark>
vue-router 提供了 beforeEachafterEach 的<mark>钩子函数</mark>, <mark>它们会在路由即将改变前和改变后触发</mark>.

## 为什么使用导航守卫?

<mark>比如说, 修改网页的标题</mark>

如果在,每一个路由对应的组件 .vue 文件中指定 title 。太麻烦

需要在每个 create 、 或者 mounte 中添加修改 title 的函数

当页面比较多时, 这种方式不容易维护(因为需要在多个页面执<mark>行类似的代码</mark>).

解决方案: 使用导航守卫即可.

## 导航守卫使用

我们可以利用 beforeEach 来完成标题的修改.

  • 首先, 我们可以在钩子(hook)当中定义一些标题, 可以利用 meta 来定义

    meta 元素的元素
    很多语言都有 meta 概念,如: metaClass

  • 其次, 利用导航守卫,修改我们的标题.

导航钩子的三个参数解析:

  • to : 即将要进入的目标的路由对象.
  • from : 当前导航即将要离开的路由对象.
  • next: 调用该方法后, 才能进入下一个钩子.

修改代码 src/router/index.js

// 配置路由的相关信息
import VueRouter from 'vue-router'
import Vue from 'vue'

// 导入自定义组件
// import Home from '../components/Home.vue'
// import About from '../components/About.vue'
// import User from '../components/User.vue'

// 通过 Vue.use(插件), 安装插件
Vue.use(VueRouter)

// 创建 VueRouter 对象
const routes = [
  {
    path: '/',
    redirect: '/home'
  }, {
    path: '/home',
    meta: {
      title: '首页'
    },
    component: () => import('../components/Home.vue'),
    children: [
      {
        path: '/home',
        redirect: '/home/news'
      },
      {
        // 注意,这里不加斜杠'/'
        path: 'news',
        component: () => import('../components/HomeNews.vue')
      },
      {
        path: 'message',
        component: () => import('../components/HomeMessage.vue')
      }
    ]
  }, {
    path: '/about',
    component: () => import('../components/About.vue'),
    meta: {
      title: '关于'
    }
  }, {
    path: '/user/:username',
    component: () => import('../components/User.vue'),
    meta: {
      title: '用户'
    },
    children: [
      {
        path: '/user/:username/profile',
        component: () => import('../components/UserProfile.vue')
      }
    ]
  }
]
const router = new VueRouter({
  // 配置路由和组件之间的响应关系
  routes,
  mode: 'history',
  linkActiveClass: 'active'
})

router.beforeEach((to, from, next) => {
  // 从 from 跳转到 to
  console.log(to)
  document.title = to.matched[0].meta.title
  next()
})

// 将 router 对象传入到 Vue 实例
export default router

## 导航守卫补充

  • 补充一:如果是<mark>后置钩子</mark>, 也就是 afterEach , 不需要主动调用 next() 函数.
  • 补充二:上面我们使用的导航守卫, 被称之为全局守卫.
    其他的守卫:
    路由独享的守卫.: 特定路由上指定的守卫
    组件内的守卫. : 写在组件里面的
    。。。
    更多 - 查看 - 【官网】

## keep-alive

<mark>用来保存用户点击记录</mark>

keep-aliveVue 内置的一个组件,可以 <mark>使被包含的组件保留状态,或避免重新渲染</mark>。
它们有两个非常重要的属性:

  • include - 字符串或正则表达,只有匹配的组件会 <mark>被缓存</mark>

  • exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存

router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存:

注意:
<keep-Alive> 配合方法 activated() 设置默认值 和 beforeRouteLeave() 记录默认值 可以实现页面的访问记录
<mark>但是,要注意。activated不能单独使用,必须在 keep-Alive 里面使用</mark>
.
后期,也会有类似的功能要实现。
不过那时,我们会用 currentIndex 。很方便

## include 、 exclude


# 案例:TabBar

文章目录