# 概念
# 理解
- 路由就是一组 key-value 的对应关系
- 多个路由,需要经过路由器配置
vue 是 SPA(single page web application)应用,使用路由进行跳转
# 使用
Vue3 中要使用 vue-router
的最新版本,目前是 4
版本
示例
配置文件 router/index.ts
import { createRouter, createWebHistory } from "vue-router"; | |
import Home from "@/pages/Home.vue"; | |
import News from "@/pages/News.vue"; | |
import About from "@/pages/About.vue"; | |
const router = createRouter({ | |
history: createWebHistory(), //history 模式 | |
routes: [ | |
{ | |
path: "/home", | |
component: Home | |
}, | |
{ | |
path: "/news", | |
component: News | |
} | |
{ | |
path: "/about", | |
component: About | |
} | |
] | |
}); | |
export default router; |
main.ts
import router from "./router/index"; // 引入路由 | |
app.use(router); // 使用路由 | |
app.mount("#app"); |
App.vue
<template> | |
<h2 class="title">Vue路由测试</h2> | |
<!-- 导航区 --> | |
<div class="navigate"> | |
<RouterLink to="/home" active-class="active">首页</RouterLink> | |
<RouterLink to="/news" active-class="active">新闻</RouterLink> | |
<RouterLink to="/about" active-class="active">关于</RouterLink> | |
</div> | |
<!-- 展示区 --> | |
<div class="main-content"> | |
<RouterView></RouterView> | |
</div> | |
</template> | |
<script lang="ts" setup name="App"> | |
import { RouterLink, RouterView } from "vue-router"; | |
</script> |
路由组件:通常存放在
pages
或views
文件夹一般组件:通常存放在
components
文件夹通过点击导航,视觉效果上 “消失” 了的路由组件,默认是被卸载掉的,需要的时候再去挂载
# 工作模式
# history 模式
- 优点:URL 更加美观,
不带有 #
,更接近传统的网站 URL - 缺点:后期项目上线,需要服务端配合处理路径问题,否则刷新会有 404 错误
const router = createRouter({ | |
history: createWebHistory() //history 模式 | |
... | |
}); |
# hash 模式
- 优点:兼容性更好,因为不需要服务器端处理路径
- 缺点:URL
带有#
不太美观,且在 SEO 优化方面相对较差
const router = createRouter({ | |
history: createWebHashHistory() //hash 模式 | |
... | |
}); |
# to 的两种写法
<!-- 字符串写法 --> | |
<router-link active-class="active" to="/home">主页</router-link> | |
<!-- 对象写法 --> | |
<router-link active-class="active" :to="{ path: '/home' }">Home</router-link> |
# 命名路由
可以简化路由跳转及传参
routes: [ | |
{ | |
name: "zhuye", | |
path: "/home", | |
component: Home | |
}, | |
{ | |
name: "xinwen", | |
path: "/news", | |
component: News | |
}, | |
{ | |
name: "guanyu", | |
path: "/about", | |
component: About | |
} | |
]; |
跳转路由
<!-- 简化前:需要写完整的路径(to 的字符串写法) --> | |
<router-link to="/news/detail">跳转</router-link> | |
<router-link :to="{ path: '/about' }">跳转</router-link> | |
<!-- 简化后:直接通过名字跳转(to 的对象写法配合 name 属性) --> | |
<router-link :to="{ name: 'guanyu' }">跳转</router-link> |
# 嵌套路由
配置路由规则
const router = createRouter({ | |
history: createWebHistory(), | |
routes: [ | |
{ | |
name: "zhuye", | |
path: "/home", | |
component: Home | |
}, | |
{ | |
name: "xinwen", | |
path: "/news", | |
component: News, | |
children: [ | |
{ | |
name: "xiang", | |
path: "detail", // 不写斜杆,访问路径:/news/detail | |
component: Detail | |
} | |
] | |
}, | |
{ | |
name: "guanyu", | |
path: "/about", | |
component: About | |
} | |
] | |
}); | |
export default router; |
跳转路由
<router-link to="/news/detail">xxxx</router-link> | |
<!-- 或 --> | |
<router-link :to="{ path: '/news/detail' }">xxxx</router-link> |
组件中预留一个 <router-view>
<template> | |
<div class="news"> | |
<nav class="news-list"> | |
<RouterLink | |
v-for="item in newsList" | |
:key="item.id" | |
:to="{ path: '/news/detail' }" | |
> | |
</RouterLink> | |
</nav> | |
<div class="news-detail"> | |
<RouterView /> | |
</div> | |
</div> | |
</template> |
# 路由传参
# query 参数
示例
传递参数
<!-- 写法一:to 的字符串写法 --> | |
<router-link | |
:to="`/news/detail?id=${item.id}&title=${item.title}&content=${item.content}`" | |
> | |
跳转 | |
</router-link> | |
<!-- 写法二:to 的对象写法 --> | |
<RouterLink | |
:to="{ | |
// name: 'xiang', // 用name也可以跳转 | |
path: '/news/detail', | |
query: { | |
id: item.id, | |
title: item.title, | |
content: item.content | |
} | |
}" | |
> | |
</RouterLink> |
接收参数
import { useRoute } from "vue-router"; | |
const route = useRoute(); | |
// 打印 query 参数 | |
console.log(route.query); |
# params 参数
示例
router/index.ts
const router = createRouter({ | |
history: createWebHistory(), | |
routes: [ | |
{ | |
name: "zhuye", | |
path: "/home", | |
component: Home | |
}, | |
{ | |
name: "xinwen", | |
path: "/news", | |
component: News, | |
children: [ | |
{ | |
name: "xiang", | |
path: "detail/:id/:title/:content?", // 占位 (? 可传可不传) | |
component: Detail | |
} | |
] | |
}, | |
{ | |
name: "guanyu", | |
path: "/about", | |
component: About | |
} | |
] | |
}); | |
export default router; |
传递参数
<!-- 写法一:to 的字符串写法 --> | |
<RouterLink :to="`/news/detail/${item.id}/${item.title}/${item.content}`"> | |
</RouterLink> | |
<!-- 写法二:to 的对象写法 --> | |
<RouterLink | |
:to="{ | |
name: 'xiang', // 用name跳转 | |
params: { | |
id: item.id, | |
title: item.title, | |
content: item.title | |
} | |
}" | |
> | |
</RouterLink> |
接收参数
import { useRoute } from "vue-router"; | |
const route = useRoute(); | |
// 打印 params 参数 | |
console.log(route.params); |
⚠️ 注:
- params 参数:若使用
to
的对象写法,必须使用name
配置项,不能用path
- params 参数:需要提前在规则中占位
# 路由的 props 配置
让路由组件更方便的收到参数(可以将路由参数作为 props
传给组件)
{ | |
name:'xiang', | |
path:'detail/:id/:title/:content', | |
component:Detail, | |
// 对象写法:把对象中的每一组 key-value 作为 props 传给 Detail 组件 | |
// props: { a:1, b:2, c:3}, | |
// <Detail /> 原本 | |
// <Detail id=? title=? conten=? /> | |
// 布尔值写法:将路由收到的所有 params 参数作为 props 传给 Detail 组件 | |
// props: true | |
// 函数写法:可以自己决定将什么作为 props 传给路由组件 | |
props(route) { | |
return route.query // | |
} | |
} |
# replace 属性
作用:控制路由跳转时操作浏览器历史记录的模式
浏览器的历史记录有两种写入方式
- push:追加历史记录(默认值)
- replace:替换当前记录
开启 replace 模式
<RouterLink replace to="/news">News</RouterLink>
# 编程式导航
脱离 <RouterLink />
进行跳转
路由组件的两个重要的属性: $route
和 $router
变成了两个 hooks
import { useRoute, useRouter } from "vue-router"; | |
const route = useRoute(); | |
const router = useRouter(); | |
// 接收路由参数 | |
console.log(route.query); | |
console.log(route.parmas); | |
// 导航 | |
console.log(router.push); | |
console.log(router.replace); |
# 重定向
将特定的路径,重新定向到已有路由
{ | |
path: '/', | |
redirect: '/home' | |
} |