[TOC] #### 1. vue-router 介绍 --- Vue-Router 3.x 适用于 Vue2,Vue-Router 4.x 适用于 Vue3 Vue-Router 3.x 官方文档: <https://router.vuejs.org/zh> vue-router 是 vue 官方的路由插件,它和 vue 是深度集成的,适合用于构建单页面应用 #### 2. vue-router 的使用 --- 安装 vue-router ``` npm install vue-router --save ``` 在模块化工程中使用 (因为它是一个插件,所以可以通过 Vue.use() 来安装路由功能) 第一步: 导入路由对象,并且调用 Vue.use(VueRouter) 第二步: 创建路由实例,并且传入路由映射配置,导出路由实例  第三步: 在 vue 实例中挂载创建的路由实例  #### 3. 路由映射配置的写法 --- 方案一: 导入组件实例 ```javascript import Home from '@/components/Home'; import About from '@/components/About'; const routes = [ { path: '/home', component: Home }, { path: '/about', component: About }, ] ``` #### 4. 路由的默认值、history 模式 --- 刚进入页面路由是 `/`, 可通过路由重定向实现默认路由 ``` { path: "", redirect: '/home' }, ``` 路由模式默认是 hash 模式,在创建路由实例时只需添加 `mode: 'history'` 即可改为 history 模式 ```javascript const router = new VueRouter({ routes, mode: 'history' }) ``` #### 5. router-link 和 router-view 组件 ---- router-link 组件用于生成路由跳转链接,to 属性用于指定路由 ``` <router-link to="/home">首页</router-link> <router-link to="/about">关于</router-link> ``` router-link 组件属性: tag router-link 组件默认会被渲染成一个 a 标签,但有些时候我们想要渲染为 li、button 标签等,此时可以使用 tag 属性 ``` <router-link to="/home" tag="li">首页</router-link> <router-link to="/about" tag="button">关于</router-link> ``` router-link 组件属性: replace 设置 replace 属性的话,当点击时,会调用 router.replace() 而不是 router.push(),于是导航后不会留下 history 记录 ``` <router-link to="/home" replace>首页</router-link> ``` router-link 组件属性: active-class 用于设置路由激活时的 CSS 类名。默认值: "router-link-active",默认值可以通过路由的构造选项 linkActiveClass 来全局配置 默认值 ```html <router-link to="/home">首页</router-link> <a href="/home" class="router-link-exact-active router-link-active" aria-current="page">首页</a> ``` 通过 active-class 属性指定类名 ```html <router-link to="/home" active-class="active">首页</router-link> <a href="/home" class="router-link-exact-active active" aria-current="page">首页</a> ``` 通过创建路由实例时的 linkActiveClass 属性指定类名 ```javascript const router = new VueRouter({ routes, linkActiveClass: "actived" }) ``` #### 6. 通过代码跳转路由 this.$router.push() --- replace 不会留下 history 记录 ```javascript this.$router.push('/home') this.$router.replace('/home') ``` #### 7. 动态路由的使用 --- 路由映射配置: 定义一个动态参数 userId ```javascript { path: '/user/:userId', component: User } ``` 进行路由跳转时 userId 是动态获取的 ```html <router-link :to="'/user/' + userId">档案</router-link> ``` 在 User 组件中获取动态参数 userId ($route: 当前处于活跃状态的路由) ``` <p>{{ $route.params.userId }}</p> ``` #### 8. 路由组件的懒加载 --- 执行打包命令 ``` npm run build ``` 当前应用程序开发的所有业务代码都在一个文件中(前缀为 app 的 js 文件) 第三方插件的东西都会打包到 vendor 前缀的 js 文件中 manifest 前缀的 js 文件是为我们打包的代码做底层支撑的 (commonjs、ES6 语法)  因为业务代码都在一个文件中,当打包构建应用时,JavaScript 包会变得非常大,影响页面加载,那么用户就会出现短暂空白的情况,所以我们应该想个办法将存放业务代码的 `app.*.js` 文件进行分离 如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了 路由懒加载的主要作用就是将路由对应的组件打包成一个个的 js 代码块,只有在这个路由被访问到时,才加载对应的组件 路由懒加载的写法 ```javascript { path: '/home', component: () => import('@/components/Home') } ``` 如下图所示,三个路由映射使用了懒加载生成了三个对应的 js 文件  #### 9. 嵌套路由的使用 --- Home 组件 ```html <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> ``` 路由映射配置 (嵌套路由: /home/news、/home/message): ``` { path: '/home', component: Home, children: [ { path: '', redirect: 'news' }, { path: 'news', component: HomeNews }, { path: 'message', component: HomeMessage }, ] }, ``` #### 10. vue-router 参数传递 --- 传递参数主要有两种方式: params 和 query | 类型 | 配置路由 | 传递方式 | 使用示例 | | ------------ | ------------ |------------ |------------ | | params | /router/:id | 在 path 后面跟上对应的值 | /router/10 | | query | /router | 对象中使用 query 的 key 作为传递方式 | /router?id=10 | router-link 组件 query 方式传递参数 ```html <router-link :to="{path: '/profile', query: {id: 10, name: 'liang'}}">档案</router-link> ``` js 代码以 query 方式传递参数 ```javascript this.$router.push({ path: "/profile", query: { id: 10, name: "liang", }, }); ``` 在 Profile 组件中获取 query 方式传递的参数 ```html <template> <div> <h2>我是Profile组件</h2> <p>{{ $route.query.id }}</p> <p>{{ $route.query.name }}</p> <button @click="btnClick">点击</button> </div> </template> ``` #### 11. 导航守卫的认识和基本使用 --- 导航守卫就是路由跳转过程中的一些钩子函数 (导航: 表示路由正在发生改变, 守卫: 可以理解为钩子) 需求: 给每个路由组件设置单独的网页标题 title 路由映射配置中添加 meta.title 属性,用于设置网页标题 (meta 是路由元信息, 也称为元数据, 就是用于描述数据的数据) ``` { path: '/home', component: Home, meta: { title: '首页' } }, { path: '/about', meta: { title: '关于' }, component: About }, ``` 全局前置守卫 ```javascript router.beforeEach((to, from, next) => { document.title = to.matched[0].meta.title next() }) ``` 补充: 全局后置守卫 ```javascript router.afterEach((to, from)=>{ console.log('afterEach ....') }) ``` 路由独享守卫需要在路由映射配置中定义: ```javascript { path: '/about', component: About, beforeEnter: (to, from, next) => { console.log('about 路由独享守卫执行') next() } }, ``` #### 12. keep-alive 组件的使用 --- keep-alive 是 vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染 router-view 是 vue-router 中的组件,如果被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存 嵌套路由保持组件选中状态: ``` data() { return { path: "/home/news", }; }, activated() { // 当组件处于活跃状态时触发 this.$router.push(this.path); }, beforeRouteLeave(to, from, next) { // 导航离开该组件的对应路由时调用 // 可以访问组件实例 `this` this.path = this.$route.path; next(); }, ``` 有些时候我们可能只需要部分组件被缓存,此时可以通过 include 或 exclude 属性来处理 include 只有匹配的组件会被缓存,exclude 匹配的组件不会被缓存 exclude 属性值是组件导入的 name 属性值,多个使用逗号分隔 ```html <keep-alive exclude="User,Profile"> <router-view /> </keep-alive> ```