# Vue 路由
路由就是Hash 地址与组件之间的对应关系
# 前端路由的工作方式
- 用户点击页面上的路由连接
- 导致了Url 地址栏中Hash值发生了变化
- 前端路由监听到了 Hash 地址的变化
- 前端路由把当前Hash 地址对应的组件渲染到浏览器中
结论:前端路由,指的是Hash 地址与组件之间的对应关系
# Vue-router
Vue-router是 vue.js 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目中组件的切换
- vue-router 3.x 只能结合vue2进行使用
- vue-router 4.x 只能结合vue3进行使用
# 声明路由链接和占位符
可以使用 <router-link>
标签来声明路由链接,并使用 <router-view>
标签来声明路由占位符
<template> | |
<div> | |
<h1>App组件</h1> | |
<!-- 声明路由连接 --> | |
<router-link to="/home">首页</router-link> | |
<router-link to="/movie">电影</router-link> | |
<router-link to="/about">关于</router-link> | |
</div> | |
</template> |
# 在 router/main.js 中导入 并注册组件
// 导入需要被展示的组件 | |
import Home from "@/views/Home.vue"; | |
import About from "@/views/About.vue"; | |
import Movie from "@/views/Movie.vue"; | |
const routes = [ | |
//path 是 hash 地址 component 是要展示的组件 | |
{path: '/home', component: Home}, | |
{path: '/about', component: About}, | |
{path: '/movie', component: Movie} | |
] |
# 路由重定向
指的是:用户在访问地址 A的时候,强制用户跳转到地址 C,从而展示特定的组件页面
用法十分简单 通过路由规则的 redirect属性,指定一个新的路由地址,可以很方便的设置路由的重定向
const routes = [ | |
//path 表示需要被重定向的 “原地址”,redirect 表示将要被重定向到的 “新地址” | |
{path: '/', redirect: '/home'}, | |
] |
# 嵌套路由
通过路由实现组件的嵌套展示,叫做嵌套路由
- 声明 子路由链接和子路由占位符
<!-- 在 About.vue 组件中,声明 tab1 和 tab2 的子路由连接以及子路由占位符 --> | |
<div class="about"> | |
<h1>About组件</h1> | |
<hr> | |
<!-- 声明子路由链接 --> | |
<router-link to="/about/tab1">tab1</router-link> | |
<router-link to="/about/tab2">tab2</router-link> | |
<hr> | |
<!-- 声明子路由占位符 --> | |
<router-view></router-view> | |
</div> |
- 在父路由规则中,通过 children属性 嵌套声明子路由规则
// 导入需要的组件 | |
import Tab1 from "@/views/tab/Table1.vue"; | |
import Tab2 from "@/views/tab/Table2.vue"; | |
const routes = [ | |
{ | |
path: '/about', | |
name: 'About', | |
component: About, | |
// 在嵌套路由中使用路由重定向 | |
redirect:'/about/tab1', | |
children: [ // 通过 children 属性嵌套子路由规则 | |
{path: 'tab1', component: Tab1}, | |
{path: 'tab2', component: Tab2}, | |
] | |
} | |
] | |
!!!注意 子路由规则的path 不要以 / 开头 | |
这样写是错误的 children:[{path:'/tab1',component:Tab1}] |
# 路由的 query 传参
跳转路由并携带 query 参数 to 的字符串写法
<router-link :to="`/home/message/detail?id=${m.id}$title=${m.title}`"> { m.title }</router-link> |
跳转路由并携带 query 参数 to 的对象写法
<router-link :to="{ | |
path:'/home/message/detail', | |
query:{ | |
id:m.id, | |
title:m.title | |
} | |
}"> | |
{ m.title } | |
</router-link> |
接收参数
$.route.query.id | |
$.route.query.title |
# 命名路由
顾名思义 就是给路由取名字 非常简单 直接加一个 name 就可以了 作用就是可以简化路由的跳转
- 使用
{path: '/about', component: About, name: 'about'}, |
- 简化
<!-- 简化前 需要写完整路劲 --> | |
<router-link to="/demo/test/welcome">欢迎</router-link> | |
<!-- 简化后 直接通过名字跳转 --> | |
<router-link to="{name:'hello'}">欢迎</router-link> | |
<!-- 检查写法配合传递参数 --> | |
<router-link :to="{ | |
name:'hello', | |
query{ | |
id:666, | |
title:'欢迎欢迎', | |
} | |
}"> | |
欢迎 | |
</router-link> |
# 动态路由匹配
指的是把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。在 vue-router 中使用英文的冒号:来定义路由的参数项
<router-link to="/movie/1">电影1</router-link> | |
<router-link to="/movie/2">电影2</router-link> | |
<router-link to="/movie/3">电影3</router-link> |
路由中的动态参数以:进行声明,冒号后面是动态参数的名称
{ path: '/movie/:id',name: 'Movie',component: Movie }, |
# 获取动态路由参数值的两种方案
- $route.params参数对象
通过动态路由匹配的方式渲染出来的组件中,可以使用 $route.params 对象访问到动态匹配的参数值
<template> | |
<div class="movie"> | |
<!--$route.params 是路由的 “参数对象”--> | |
<h1>Movie组件---------{ $route.params.id }</h1> | |
</div> | |
</template> |
- 使用 props 接收路由参数
为了简化路由参数的获取形式,vue-router 允许 路由规则中开启 props 传参
// 在 movie 组件中 以 props 的形式接收到路由规则匹配到的参数项 | |
// 第一种写法,值为对象,该对象中所有的 key-value 都会以 props 的形式传给 Movie 组件 | |
{ path: '/movie/:id', name: 'Movie', component: Movie, props: {a:1,b:'hello'} }, | |
// 第二种写法,值为布尔值,如果 props 的值为 true 就会把该路由组件收到的所有 params 参数,以 props 的形式传给 Movie 组件 | |
{ path: '/movie/:id', name: 'Movie', component: Movie, props: true }, | |
// 第三种写法,值为函数 | |
props($route){ | |
return {id:$route.query.id,title:$route.query.title} | |
} |
// 在 movie 组件中使用 props 接收路由规则中匹配到的参数项 | |
props: ['id'] |
<!-- 直接使用 props 中接收的路由参数 --> | |
<h1>Movie组件----{ id }</h1> |
# 编程式导航
通过调用 API实现导航的方式,叫做编程式导航,与之对应的,通过点击链接实现导航的方式,叫做声明式导航
- 普通网页中点击a 链接,vue 项目中点击router-link都属于声明式导航
- 普通网页中调用location.href跳转到新页面的方式,属于编程式导航
# vue-router 中的编程式
vue-router 提供了许多编程式导航 API,其中最常用的两个 API 分别是
- this.$router.push ('hash 地址 ')
- 跳转到指定 hash 地址,从而展示对应的组件
- this.$router.go (数值 n)
- 实现导航历史的前进,后退
# 路由守卫
路由守卫可以控制路由的访问权限
router.beforeEach((to, form, next) => { | |
//to 目标路由对象 | |
//from 当前导航正要离开的路由对象 | |
//next 是一个函数 表示放行 | |
const token = localStorage.getItem('token') | |
if (to.path === '/main' && !token) { | |
//next (false) 不允许跳转 | |
next('/login') // 强制跳转到 “登录页面” | |
} else { | |
next() // 直接放行, 允许访问 “后台主页” | |
} | |
}) |
# 路由器的两种工作模式
- hash 模式:
- 地址中永远带着 #号 不美观
- 若以后将地址通过第三方手机 app 分享,诺 app 效验严格,则地址会被标记为不合法。
- 兼容性较好
- history 模式
- 地址干净,美观
- 兼容性和 hash 模式相比略差
- 应用部署上线时需要后端人员支持,解决刷新页面服务端 404 问题