3.5.3 next 函数的 3 种调用方式
当前用户拥有后台主页的访问权限,直接放行:next()
当前用户没有后台主页的访问权限,强制其跳转到登录页面:next(‘/login’)
当前用户没有后台主页的访问权限,不允许跳转到后台主页,强制其停留在当前页面:next(false)
3.5.4 控制后台主页的访问权限
// 为 router 实例对象,声明全局前置导航守卫 // 只要发生了路由的跳转,必然会触发 beforeEach 指定的 function 回调函数 router.beforeEach(function(to, from, next) { // to 表示将要访问的路由的信息对象 // from 表示将要离开的路由的信息对象 // next() 函数表示放行的意思 // 分析: // 1. 要拿到用户将要访问的 hash 地址 // 2. 判断 hash 地址是否等于 /main。 // 2.1 如果等于 /main,证明需要登录之后,才能访问成功 // 2.2 如果不等于 /main,则不需要登录,直接放行 next() // 3. 如果访问的地址是 /main。则需要读取 localStorage 中的 token 值 // 3.1 如果有 token,则放行 // 3.2 如果没有 token,则强制跳转到 /login 登录页 if (to.path === '/main') { // 要访问后台主页,需要判断是否有 token const token = localStorage.getItem('token') if (token) { next() } else { // 没有登录,强制跳转到登录页 // next(false) // 不允许跳转 next('/login') } } else { next() } })
src/router/index.js
// src/router/index.js 就是当前项目的路由模块 // 导入Vue和VueRouter包 import Vue from 'vue' import VueRouter from 'vue-router' // 导入需要的组件 import Home from '@/components/Home.vue' import Movie from '@/components/Movie.vue' import About from '@/components/About.vue' import Tab1 from '@/components/tabs/Tab1.vue' import Tab2 from '@/components/tabs/Tab2.vue' import Login from '@/components/Login.vue' import Main from '@/components/Main.vue' // 把 VueRouter 安装为 Vue 项目的插件 // Vue.use() 函数的作用,就是来安装插件的 Vue.use(VueRouter) // 创建路由的实例对象 const router = new VueRouter({ // routes 是一个数组,作用:定义 “hash 地址” 与 “组件” 之间的对应关系 routes: [ // 重定向的路由规则 { path: '/', redirect: '/home' }, // 路由规则 { path: '/home', component: Home }, // 需求:在 Movie 组件中,希望根据 id 的值,展示对应电影的详情信息 // 可以为路由规则开启 props 传参,从而方便的拿到动态参数的值 { path: '/movie/:mid', component: Movie, props: true }, { path: '/about', component: About, // redirect: '/about/tab1', children: [ // 子路由规则 // 默认子路由:如果 children 数组中,某个路由规则的 path 值为空字符串,则这条路由规则,叫做“默认子路由” { path: '', component: Tab1 }, { path: 'tab2', component: Tab2 } ] }, { path: '/login', component: Login }, { path: '/main', component: Main } ] }) // 为 router 实例对象,声明全局前置导航守卫 // 只要发生了路由的跳转,必然会触发 beforeEach 指定的 function 回调函数 router.beforeEach(function(to, from, next) { // to 表示将要访问的路由的信息对象 // from 表示将要离开的路由的信息对象 // next() 函数表示放行的意思 // 分析: // 1. 要拿到用户将要访问的 hash 地址 // 2. 判断 hash 地址是否等于 /main。 // 2.1 如果等于 /main,证明需要登录之后,才能访问成功 // 2.2 如果不等于 /main,则不需要登录,直接放行 next() // 3. 如果访问的地址是 /main。则需要读取 localStorage 中的 token 值 // 3.1 如果有 token,则放行 // 3.2 如果没有 token,则强制跳转到 /login 登录页 if (to.path === '/main') { // 要访问后台主页,需要判断是否有 token const token = localStorage.getItem('token') if (token) { next() } else { // 没有登录,强制跳转到登录页 next('/login') } } else { next() } }) // 向外共享路由的实例对象 export default router
3.6 路由高亮
Vue3
可以通过如下的两种方式,将激活的路由链接进行高亮显示:
① 使用默认的高亮 class 类
② 自定义路由高亮的 class 类
3.6.1 默认的高亮 class 类
被激活的路由链接,默认会应用一个叫做 router-link-active 的类名。开发者可以使用此类名选择器,为激活的路由链接设置高亮的样式:
/*在index.css全局样式表中,重新router-link-active 的样式*/ .router-link-active { background-color : red; color : white; font-weight: bold; }
3.6.2 自定义路由高亮的 class 类
在创建路由的实例对象时,开发者可以基于 linkActiveClass 属性,自定义路由链接被激活时所应用的类名:
// 从 vue-router 中按需导入两个方法 import { createRouter, createWebHashHistory } from 'vue-router' import Home from './MyHome.vue' import Movie from './MyMovie.vue' import About from './MyAbout.vue' // 创建路由对象 const router = createRouter({ // 指定路由的工作模式 history: createWebHashHistory(), // 自定义路由高亮的 class 类 //指定被激活的路由链接,会应用 active-router 这个类名, //默认的router-link-active类名会被覆盖掉 linkActiveClass: 'active-router', // 声明路由的匹配规则 routes: [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, { path: '/movie', component: Movie }, { path: '/about', component: About }, ], }) // 导出路由对象 export default router
3.7 命名路由
通过 name 属性为路由规则定义名称的方式,叫做命名路由。
// 动态路由匹配 { name: 'mov', path: '/movie/:mid', component: Movie, props: true },
// 创建路由对象 const router = createRouter({ // 指定路由的工作模式 history: createWebHashHistory(), // 自定义路由高亮的 class 类 linkActiveClass: 'active-router', // 声明路由的匹配规则 routes: [ { path: '/', redirect: '/home' }, { path: '/home', component: Home }, // 动态路由匹配 { name: 'mov', path: '/movie/:mid', component: Movie, props: true }, { path: '/about', component: About, // 嵌套路由的重定向 redirect: '/about/tab1', // 通过 children 属性嵌套声明子级路由规则 children: [ { path: 'tab1', component: Tab1 }, { path: 'tab2', component: Tab2 }, ], }, ], })
注意:命名路由的 name 值不能重复,必须保证唯一性!
3.7.1 使用命名路由实现声明式导航
为 <router-link>
标签动态绑定 to 属性的值,并通过 name 属性指定要跳转到的路由规则。期间还可以用params 属性指定跳转期间要携带的路由参数。
<router-link :to="{ name: 'mov', params: { mid: 2 } }">go to movie</router-link
3.7.2 使用命名路由实现编程式导航
调用 push 函数期间指定一个配置对象,name 是要跳转到的路由规则、params 是携带的路由参数。
<template> <div> <h3>MyHome 组件</h3> <router-link :to="{ name: 'mov', params: { mid: 2 } }">go to movie</router-link> <button type="button" class="btn btn-primary" @click="goToMovie(1)">go to movie</button> </div> </template> <script> export default { name: 'MyHome', methods: { goToMovie(id) { this.$router.push({ name: 'mov', params: { mid: id, }, }) }, }, } </script> <style lang="less" scoped></style>
Movie.vue
<template> <div> <h3>MyMovie 组件 --- {{ $route.params.mid }} --- {{ mid }}</h3> </div> </template> <script> export default { name: 'MyMovie', props: ['mid'], } </script> <style lang="less" scoped></style>
4