Vue3 --- 路由
1. 模块下载
npm i vue-router
2. 基本使用
1. 指定路由规则
src/router/index.ts
import { createRouter, createWebHashHistory } from "vue-router";
import Home from "@/components/Home.vue"
import News from "@/components/News.vue"
import About from "@/components/About.vue"
// 创建路由器并暴露
export default createRouter({
// 路由器的工作模式: history 模式
history: createWebHashHistory(),
// 路由规则
routes:[
{
path: "/home",
component: Home
},
{
path: "/news",
component: News
},
{
path: "/about",
component: About
}
]
})
2. 使用路由器
src/main.ts
import {createApp} from 'vue'
import App from './App.vue'
import router from './router'
// 创建 App 应用
const app = createApp(App)
// 使用 router 路由器
app.use(router)
// 股灾整个应用到 app 容器中
app.mount('#app')
3. 页面中指定路由
App.vue
<template>
<div class="app">
<!-- 标题 -->
<h2>Vue 路由测试</h2>
<!-- 导航区 -->
<div class="nav">
<!-- 3. 使用 RouterLink 标签 包裹需要点击跳转的路由 -->
<!-- active-class="active" 表示当前路由被激活时候的 css 样式 -->
<RouterLink to="/home" active-class="active">首页</RouterLink>
<!-- to 的 字符串 写法 -->
<RouterLink to="/news" active-class="active">新闻</RouterLink>
<!-- to 的 对象 写法, path 是固定 key -->
<RouterLink :to="{path: '/about'}" active-class="active">关于</RouterLink>
</div>
<!-- 内容展示区 -->
<div class="content">
<!-- 2. 使用 RouterView 标签来表示组件内容展示在这里 -->
<RouterView></RouterView>
</div>
</div>
</template>
<script lang="ts" setup name="App">
// 1. 引入 RouterView
import {RouterView,RouterLink} from 'vue-router'
</script>
<style scoped>
h2{
width: 100%;
height: 100px;
background-color: aliceblue;
text-align: center;
line-height: 100px;
}
.nav{
display: flex;
justify-content: space-around;
}
.nav a{
width: 80px;
height: 38px;
border-radius: 15px;
align-content: center;
text-align: center
}
.nav a.active{
background-color: rgb(44, 223, 139);
}
.content{
width: 1200px;
height: 500px;
border: 1px solid black;
border-radius: 20px;
margin-top: 50px;
}
</style>
src/views/Home.vue
<template>
<h2>Home</h2>
</template>
<script lang="ts" setup name="Home">
</script>
src/views/News.vue
<template>
<h2>News</h2>
</template>
<script lang="ts" setup name="News">
</script>
src/views/About.vue
<template>
<h2>About</h2>
</template>
<script lang="ts" setup name="About">
</script>
3. 注意
- 路由组件通常放在
pages或views文件夹中, 一般组件通常放在components文件夹 - 通过点击导航, 视觉效果上
消失了的路由组件, 默认是被销毁掉的, 需要的时候再去挂载
4. 三种跳转方式
1. 字符串
<RouterLink to="/home" active-class="active">首页</RouterLink>
2. 对象
<RouterLink :to="{path: '/about'}" active-class="active">关于</RouterLink>
3. 命名空间
router/index.ts
import { createRouter, createWebHistory } from "vue-router";
import Home from "@/components/Home.vue"
import News from "@/components/News.vue"
import About from "@/components/About.vue"
export default createRouter({
history: createWebHistory(),
routes:[
{
name: "home", // 添加名字
path: "/home",
component: Home
},
{
name: "news",
path: "/news",
component: News
},
{
name: "about",
path: "/about",
component: About
}
]
})
页面中跳转
<RouterLink :to="{name: 'about'}" active-class="active">关于</RouterLink>
5. 两种工作模式
1. history 模式
优点: URL 更美观, 不带有 #, 更接近于传统网站的 URL
缺点: 后期项目上线, 需要服务端配置处理路径问题, 否则刷新就会有 404 错误
应用场景: TOC 的网站一般使用 history 模式, 如 B站
import { createWebHistory } from "vue-router";
export default createRouter({
history: createWebHistory(),
// ......
}
后端处理路径问题: Vue3 ---- 部署
2. hash 模式
优点: 兼容性更好, 因为不需要服务器端处理路径
缺点: URL 带有 # 不太美观, 且在 SEO 优化方面相对较差
应用场景: 后台管理系统等, 一般使用 hash 模式
import { createWebHashHistory } from "vue-router";
export default createRouter({
history: createWebHashHistory(),
// ......
}
5. 嵌套路由
src/router/index.ts
import { createRouter, createWebHistory } from "vue-router";
import Home from "@/components/Home.vue"
import News from "@/components/News.vue"
import About from "@/components/About.vue"
import Detail from "@/components/Detail.vue"
export default createRouter({
history: createWebHistory(),
routes:[
{
name: "home",
path: "/home",
component: Home
},
{
name: "news",
path: "/news",
component: News,
// 配置子路由
children:[
{
path: "detail", // 子路由不用写 /
component: Detail,
}
]
},
{
name: "about",
path: "/about",
component: About
}
]
})
src/views/news.vue
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<!-- RouterLink 定义跳转标签, to 定义跳转链接, 链接需要从根路由开始写全 -->
<li v-for="n in news" :key="n.id"><RouterLink to="/news/detail">{{ n.title }}</RouterLink></li>
</ul>
<!-- 展示区 -->
<div class="new-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script lang="ts" setup name="News">
import { reactive } from 'vue';
import {RouterView,RouterLink} from 'vue-router'
const news = reactive([
{
id: 'adfasdfc01',
title: '十种抗癌食物',
content: '西蓝花'
},
{
id: 'adfasdfc02',
title: '母猪的产后护理',
content: '吃喝'
},
{
id: 'adfasdfc03',
title: '小明竟然...',
content: '打了个喷嚏'
}
])
</script>
<style>
.news{
display: flex;
}
.new-content{
width: 1000px;
height: 420px;
border: 1px solid black;
border-radius: 20px;
margin-top: 50px;
}
</style>
6. 路由传参
1. query 参数
1. 父组件传参
<ul>
<li v-for="n in news" :key="n.id">
<!-- 方式一: 字符串拼接写法 -->
<RouterLink :to="`/news/detail?id=${n.id}&title=${n.title}&content=${n.content}`">{{ n.title }}</RouterLink>
<!-- 方式二: 对象写法 -->
<RouterLink
:to="{
path: '/news/detail',
query:{
id:n.id,
title: n.title,
content: n.content
}
}"
>
{{ n.title }}
</RouterLink>
<!-- 方式三: 命名空间写法, 前提需要在路由规则中添加 name: "detail" -->
<RouterLink
:to="{
name: 'detail',
query:{
id:n.id,
title: n.title,
content: n.content
}
}"
>
{{ n.title }}
</RouterLink>
</li>
</ul>
2. 子组件接受参数
方式一: useRoute 中提取传过来的 query 参数
<template>
<div>
编号: <span> {{ query.id }}</span>
</div>
<div>
标题: <span>{{ query.title }}</span>
</div>
<div>
内容: <span>{{ query.content }}</span>
</div>
</template>
<script lang="ts" setup name="Detail">
// 1. 导入 toRefs, useRoute hook 函数
import { toRefs } from 'vue';
import { useRoute } from 'vue-router'
// 2. 调用 hook 函数, 并赋值
let route = useRoute()
// 3. 从 route.query 中解构 query 参数, 必须使用 toRefs 将 route 变成一个响应式
const {query} =toRefs(route)
</script>
方式二: props 提取传过来的 query 参数
在 路由规则中 配置使用 props 方式来传递 query 参数
import { createRouter, createWebHistory } from "vue-router";
import Home from "@/components/Home.vue"
import News from "@/components/News.vue"
import About from "@/components/About.vue"
import Detail from "@/components/Detail.vue"
export default createRouter({
history: createWebHistory(),
routes:[
{
name: "home",
path: "/home",
component: Home
},
{
name: "news",
path: "/news",
component: News,
children:[
{
name:"detail",
path: "detail",
component: Detail,
// 函数写法: 可以自己决定将什么作为 props 参数
props(route) {
return route.query
}
}
]
},
{
name: "about",
path: "/about",
component: About
}
]
})
在 子组件 中接受 props 传递的数据
<template>
<div>
编号: <span> {{ id }}</span>
</div>
<div>
标题: <span>{{ title }}</span>
</div>
<div>
内容: <span>{{ content }}</span>
</div>
</template>
<script lang="ts" setup name="Detail">
defineProps(['id',"title","content"])
</script>
2. params 参数
1. 修改路由规则
import { createRouter, createWebHistory } from "vue-router";
import Home from "@/components/Home.vue"
import News from "@/components/News.vue"
import About from "@/components/About.vue"
import Detail from "@/components/Detail.vue"
export default createRouter({
history: createWebHistory(),
routes:[
{
name: "home",
path: "/home",
component: Home
},
{
name: "news",
path: "/news",
component: News,
children:[
{
name:"detail",
path: "detail/:id/:title/:content?", // 传递 params 参数必须先使用此规则占位, ?表示此参数非必要
component: Detail,
}
]
},
{
name: "about",
path: "/about",
component: About
}
]
})
2. 父组件传递参数
<ul>
<li v-for="n in news" :key="n.id">
<!-- 方式一: 字符串写法 -->
<RouterLink :to="`/news/detail/${n.id}/${n.title}/${n.content}/`">{{ n.title }}</RouterLink>
<!-- 方式二: 对象写法 -->
<RouterLink
:to="{
name: 'detail', // 传递 params 参数 只能使用 name 方式, 前提需要在路由规则中添加 name: "detail"
params:{ // params 中的值不能为 对象 或 数组
id:n.id,
title: n.title,
content: n.content
}
}"
>
{{ n.title }}
</RouterLink>
</li>
</ul>
3. 子组件接受参数
方式一: useRoute 中提取传过来的 params 参数
<template>
<div>
编号: <span> {{ params.id }}</span>
</div>
<div>
标题: <span>{{ params.title }}</span>
</div>
<div>
内容: <span>{{ params.content }}</span>
</div>
</template>
<script lang="ts" setup name="Detail">
// 1. 导入 toRefs, useRoute hook 函数
import { toRefs } from 'vue';
import { useRoute } from 'vue-router';
// 2. 调用 hook 函数, 并赋值
let route = useRoute()
// 3. 从 route.query 中解构 params 参数, 必须使用 toRefs 将 route 变成一个响应式
const {params} = toRefs(route)
</script>
方式二: props 提取传过来的 params 参数
在 路由规则中 配置使用 props 方式来传递 params 参数
import { createRouter, createWebHistory } from "vue-router";
import Home from "@/components/Home.vue"
import News from "@/components/News.vue"
import About from "@/components/About.vue"
import Detail from "@/components/Detail.vue"
export default createRouter({
history: createWebHistory(),
routes:[
{
name: "home",
path: "/home",
component: Home
},
{
name: "news",
path: "/news",
component: News,
children:[
{
name:"detail",
path: "detail/:id/:title/:content?",
component: Detail,
props: true // 配置项写法: 将路由收到的 params 参数, 转化为 props 传递给子组件, 子组件可以使用 props 来读取 params 参数 (推荐)
// 函数写法: 可以自己决定将什么作为 props 参数
props(route) {
return route.params.params
}
}
]
},
{
name: "about",
path: "/about",
component: About
}
]
})
在 子组件 中接受 props 传递的数据
<template>
<div>
编号: <span> {{ id }}</span>
</div>
<div>
标题: <span>{{ title }}</span>
</div>
<div>
内容: <span>{{ content }}</span>
</div>
</template>
<script lang="ts" setup name="Detail">
defineProps(['id',"title","content"])
</script>
7. repalce 属性
**push模式( 默认 ): ** 将访问路径 push 到栈底, 浏览器中可以前进后退
replace模式 将访问路径替换之前的路径, 浏览器中无法前进后退
<!-- 添加 replace 属性 -->
<RouterLink replace to="/home" active-class="active">首页</RouterLink>
8. 编程式导航 ( 路由跳转 )
1. 简单使用
**需求: ** 3 秒后跳转到首页
<template>
<div class="nav">
<RouterLink to="/home">首页</RouterLink>
</div>
<div class="content">
<RouterView></RouterView>
</div>
</template>
<script setup lang="ts" name="App">
import {onMounted} from "vue";
// 1. 导入 useRouter
import {useRouter} from "vue-router";
// 2. 接收 router
const router = useRouter();
onMounted(()=>{
setTimeout(()=>{
// 3. 跳转到首页
router.push("/home")
},3000)
})
</script>
<style scoped>
.content{
width: 1200px;
height: 800px;
border: 1px solid black;
border-radius: 25px;
margin-top: 30px;
}
</style>
2. 携带参数
跟 RouterLink 的 to 所传的参数保持一致
<template>
<div class="nav">
<RouterLink to="/home">首页</RouterLink>
<button @click="toHome">跳转到首页</button>
</div>
<div class="content">
<RouterView></RouterView>
</div>
</template>
<script setup lang="ts" name="App">
import {onMounted} from "vue";
// 1. 导入 useRouter
import {useRouter} from "vue-router";
// 2. 接收 router
const router = useRouter();
const a = 1
const b = 2
// 跳转到首页
function toHome() {
// 3. 跳转到首页, 并携带 query 参数
router.push({
path: '/home',
query:{
a,
b
}
})
}
</script>
<style scoped>
.content{
width: 1200px;
height: 800px;
border: 1px solid black;
border-radius: 25px;
margin-top: 30px;
}
</style>
9. 重定向
src/router/index.ts
import {createRouter, createWebHistory} from "vue-router";
import Home from "@/components/Home.vue"
export default createRouter({
history: createWebHistory(),
routes: [
{
name: "home",
path: "/home",
component: Home
},
{
path: "/",
redirect: "/home", // 对于根路径 / 的请求, 重定向到 /home 路径
}
]
})

浙公网安备 33010602011771号