路由介绍
Vue 3 的路由功能是构建单页应用(SPA)的核心部分,它允许根据 URL 的变化动态加载不同的组件。
例如这个就是单页应用 他有导航区和展示区 点击每个导航 展示区展示的内容都不变 但是他只是一个页面
下面是使用路由模拟一个简单单页应用的效果的步骤
- 在项目中创建一个 router 文件夹,并在其中创建 index.js 文件来配置路由
//创建一个路由器 并且将他暴露出去
//1.引入createRouter
import {createRouter,createWebHistory} from 'vue-router'
import Home from '@/components/Home.vue'
import About from '@/components/About.vue'
import News from '@/components/News.vue'
//2.创建路由器
const router=createRouter({
history:createWebHistory(),
routes:[//一个一个的路由规则
{
path:'/home',
component:Home
},
{
path:'/news',
component:News
},
{
path:'/about',
component:About
}
]
})
//暴露出去
export default router
- 在 main.js 中引入并使用路由
// 导入 Vue 的 createApp 方法,用于创建 Vue 应用
import { createApp } from "vue";
// 导入本地的 App 组件,这是应用的根组件
import App from "./App.vue";
//引入路由器
import router from "./router";
//创建一个应用
const app=createApp(App);
//使用路由器
app.use(router)
app.mount('#app')
- 路由的基本使用使用
router-link
和router-view
在 Vue 3 中, 用于定义导航链接,而router-view
用于显示当前路由对应的组件
<template>
<div class="app">
<Header/>
<!-- 导航区 -->
<div class="navigate">
<RouterLink :to="{
path:'/home'
}" active-class="active">首页</RouterLink>
<RouterLink :to="{
path:'/news'
}" active-class="active">新闻</RouterLink>
<RouterLink :to="{
path:'about'
}" active-class="active">关于</RouterLink>
</div>
<!-- 内容区 -->
<div class="main-content">
<router-view></router-view>
</div>
</div>
</template>
<script lang="ts" setup name="App">
import { RouterView ,RouterLink} from 'vue-router';
import Header from '@/components/Header.vue'
</script>
<style>
/* 基础样式 */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}
.app {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background-color: #fff;
box-shadow:0 0 10px rgba(0, 0, 0, 0.1);
}
/* 导航区样式 */
.navigate {
display: flex;
justify-content: center;
margin-bottom: 30px;
}
.navigate a {
display: inline-block;
padding: 10px 20px;
margin: 0 10px;
text-decoration: none;
color: #333;
font-weight: bold;
border: 2px solid #333;
border-radius: 5px;
transition: background-color 0.3s, color 0.3s;
}
.navigate a:hover {
background-color: #333;
color: #fff;
}
/* 内容区样式 */
.main-content {
background-color: #f9f9f9;
padding: 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.navigate a.active {
background-color: #333; /* 激活时的背景颜色 */
color: #fff; /* 激活时的文字颜色 */
border-color: #333; /* 激活时的边框颜色 */
}
</style>
- 两个注意点
路由组件通常存放在pages
或views
文件夹,一般组件通常存放在components
文件夹。
通过点击导航,视觉效果上“消失” 了的路由组件,默认是被卸载掉的,需要的时候再去挂载。
写路由组件
- 路由组件About.vue
<template>
<div class="about">
<h2>你也喜欢看海贼王?</h2>
</div>
</template>
<script setup lang="ts" name="About">
</script>
<style scoped>
h2{
margin-left: 45%;
}
</style>
- 路由组件Home.vue
<template>
<div class="home">
<h2>海贼王真好看</h2>
</div>
</template>
<script setup lang="ts" name="Home">
</script>
<style scoped>
h2{
margin-left: 45%;
}
</style>
- 路由组件News.vue
<template>
<div class="news">
<ul>
<li><a href="#">新闻001</a></li>
<li><a href="#">新闻002</a></li>
<li><a href="#">新闻003</a></li>
<li><a href="#">新闻004</a></li>
</ul>
</div>
</template>
<script setup lang="ts" name="News">
</script>
<style scoped>
/* 新闻列表容器样式 */
.news {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
/* 列表样式 */
.news ul {
list-style: none; /* 去掉默认的列表样式 */
padding: 0;
margin: 0;
}
/* 列表项样式 */
.news li {
margin-bottom: 10px; /* 添加间距 */
}
/* 链接样式 */
.news a {
display: block; /* 使链接占据整个列表项 */
padding: 10px;
text-decoration: none; /* 去掉下划线 */
color: #333; /* 文字颜色 */
border: 2px solid transparent; /* 默认无边框 */
border-radius: 5px; /* 圆角 */
transition: background-color 0.3s, border-color 0.3s; /* 平滑过渡效果 */
}
/* 链接悬停样式 */
.news a:hover {
background-color: #f0f0f0; /* 悬停时的背景颜色 */
border-color: #ccc; /* 悬停时的边框颜色 */
}
/* 链接激活样式(可选) */
.news a.active {
background-color: #333; /* 激活时的背景颜色 */
color: #fff; /* 激活时的文字颜色 */
border-color: #333; /* 激活时的边框颜色 */
}
</style>
写一般组件
- Header.vue
<template>
<div class="about">
<h1>路由测试</h1>
</div>
</template>
<script setup lang="ts" name="Header">
</script>
<style scoped>
h1 {
text-align: center;
color: #333;
margin-bottom: 20px;
}
</style>
效果样式
点击首页的效果样式
点击新闻的效果样式
点击关于的效果样式
嵌套路由
配置子路由规则,使用children
配置项
//创建一个路由器 并且将他暴露出去
//1.引入createRouter
import {createRouter,createWebHistory} from 'vue-router'
import Home from '@/pages/Home.vue'
import About from '@/pages/About.vue'
import News from '@/pages/News.vue'
import Detail from '@/pages/Detail.vue'
//2.创建路由器
const router=createRouter({
history:createWebHistory(),
routes:[//一个一个的路由规则
{
path:'/home',
component:Home
},
{
path:'/news',
component:News,
children:[{
name:'xiang',
path:'detail',
component:Detail
}]
},
{
path:'/about',
component:About
}
]
})
//暴露出去
export default router
query参数
路由组件Detail.vue
<template>
<ul class="news-list">
<li>编号:{{ query.id }}</li>
<li>姓名:{{ query.name }}</li>
<li>能力:{{ query.ability }}</li>
</ul>
</template>
<script setup lang="ts" name="Detail">
import { useRoute } from 'vue-router';
import { toRefs } from 'vue';
let route=useRoute()
let {query} =toRefs(route)
</script>
<style scoped>
h2{
margin-left: 45%;
}
</style>
携带query参数的子路由
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<RouterLink
:to="{
path:'/news/detail',
query:{
id:news.id,
name:news.name,
ability:news.ability
}
}">{{news.name}}</RouterLink>
</li>
</ul>
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script setup lang="ts" name="News">
import { reactive } from 'vue';
import { RouterView ,RouterLink} from 'vue-router';
let newsList=reactive([
{id:'dadada1',name:'路飞',ability:'橡胶果实'},
{id:'dadada2',name:'白胡子',ability:'地震果实'},
{id:'dadada3',name:'黑胡子',ability:'暗暗果实'},
{id:'dadada4',name:'艾斯',ability:'炎炎果实'}
])
</script>
<style scoped>
/* 新闻列表容器样式 */
.news {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
/* 列表样式 */
.news ul {
list-style: none; /* 去掉默认的列表样式 */
padding: 0;
margin: 0;
}
/* 列表项样式 */
.news li {
margin-bottom: 10px; /* 添加间距 */
}
/* 链接样式 */
.news a {
display: block; /* 使链接占据整个列表项 */
padding: 10px;
text-decoration: none; /* 去掉下划线 */
color: #333; /* 文字颜色 */
border: 2px solid transparent; /* 默认无边框 */
border-radius: 5px; /* 圆角 */
transition: background-color 0.3s, border-color 0.3s; /* 平滑过渡效果 */
}
/* 链接悬停样式 */
.news a:hover {
background-color: #f0f0f0; /* 悬停时的背景颜色 */
border-color: #ccc; /* 悬停时的边框颜色 */
}
/* 链接激活样式(可选) */
.news a.active {
background-color: #333; /* 激活时的背景颜色 */
color: #fff; /* 激活时的文字颜色 */
border-color: #333; /* 激活时的边框颜色 */
}
</style>
点击路飞 展示路飞的详情
点击艾斯 展示艾斯的详情
params参数
注意
传递params
参数时,若使用to
的对象写法,必须使用name
配置项,不能用path
传递params
参数时,需要提前在规则中占位
路由规则
//创建一个路由器 并且将他暴露出去
//1.引入createRouter
import {createRouter,createWebHistory} from 'vue-router'
import Home from '@/pages/Home.vue'
import About from '@/pages/About.vue'
import News from '@/pages/News.vue'
import Detail from '@/pages/Detail.vue'
//2.创建路由器
const router=createRouter({
history:createWebHistory(),
routes:[//一个一个的路由规则
{
path:'/home',
component:Home
},
{
path:'/news',
component:News,
children:[{
name:'xiang',
path:'detail/:id/:name/:ability',
component:Detail
}]
},
{
path:'/about',
component:About
}
]
})
//暴露出去
export default router
<template>
<ul class="news-list">
<li>编号:{{ params.id }}</li>
<li>姓名:{{ params.name }}</li>
<li>能力:{{ params.ability }}</li>
</ul>
</template>
<script setup lang="ts" name="Detail">
import { useRoute } from 'vue-router';
import { toRefs } from 'vue';
let route=useRoute()
let {params} =toRefs(route)
</script>
<style scoped>
h2{
margin-left: 45%;
}
</style>
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<RouterLink
:to="{
name:'xiang',
params:{
id:news.id,
name:news.name,
ability:news.ability
}
}">{{news.name}}</RouterLink>
</li>
</ul>
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script setup lang="ts" name="News">
import { reactive } from 'vue';
import { RouterView ,RouterLink} from 'vue-router';
let newsList=reactive([
{id:'dadada1',name:'路飞',ability:'橡胶果实'},
{id:'dadada2',name:'白胡子',ability:'地震果实'},
{id:'dadada3',name:'黑胡子',ability:'暗暗果实'},
{id:'dadada4',name:'艾斯',ability:'炎炎果实'}
])
</script>
<style scoped>
/* 新闻列表容器样式 */
.news {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
/* 列表样式 */
.news ul {
list-style: none; /* 去掉默认的列表样式 */
padding: 0;
margin: 0;
}
/* 列表项样式 */
.news li {
margin-bottom: 10px; /* 添加间距 */
}
/* 链接样式 */
.news a {
display: block; /* 使链接占据整个列表项 */
padding: 10px;
text-decoration: none; /* 去掉下划线 */
color: #333; /* 文字颜色 */
border: 2px solid transparent; /* 默认无边框 */
border-radius: 5px; /* 圆角 */
transition: background-color 0.3s, border-color 0.3s; /* 平滑过渡效果 */
}
/* 链接悬停样式 */
.news a:hover {
background-color: #f0f0f0; /* 悬停时的背景颜色 */
border-color: #ccc; /* 悬停时的边框颜色 */
}
/* 链接激活样式(可选) */
.news a.active {
background-color: #333; /* 激活时的背景颜色 */
color: #fff; /* 激活时的文字颜色 */
border-color: #333; /* 激活时的边框颜色 */
}
</style>
点击路飞 展示路飞的详情
点击艾斯 展示艾斯的详情
props
当接收的是params参数时
<template>
<ul class="news-list">
<li>编号:{{ id }}</li>
<li>姓名:{{ name }}</li>
<li>能力:{{ ability }}</li>
</ul>
</template>
<script setup lang="ts" name="Detail">
defineProps(['id','name','ability'])
</script>
<style scoped>
h2{
margin-left: 45%;
}
</style>
//创建一个路由器 并且将他暴露出去
//1.引入createRouter
import {createRouter,createWebHistory} from 'vue-router'
import Home from '@/pages/Home.vue'
import About from '@/pages/About.vue'
import News from '@/pages/News.vue'
import Detail from '@/pages/Detail.vue'
//2.创建路由器
const router=createRouter({
history:createWebHistory(),
routes:[//一个一个的路由规则
{
path:'/home',
component:Home
},
{
path:'/news',
component:News,
children:[{
name:'xiang',
path:'detail/:id/:name/:ability',
component:Detail,
props:true
}]
},
{
path:'/about',
component:About
}
]
})
//暴露出去
export default router
点击路飞 展示路飞的详情
点击艾斯 展示艾斯的详情
当传递的是query参数
//创建一个路由器 并且将他暴露出去
//1.引入createRouter
import {createRouter,createWebHistory} from 'vue-router'
import Home from '@/pages/Home.vue'
import About from '@/pages/About.vue'
import News from '@/pages/News.vue'
import Detail from '@/pages/Detail.vue'
//2.创建路由器
const router=createRouter({
history:createWebHistory(),
routes:[//一个一个的路由规则
{
path:'/home',
component:Home
},
{
path:'/news',
component:News,
children:[{
name:'xiang',
path:'detail/:id/:name/:ability',
component:Detail,
props(route){
return route.query
}
}]
},
{
path:'/about',
component:About
}
]
})
//暴露出去
export default router
点击路飞 展示路飞的详情
编程式路由导航
一个简单的编程式路由导航 当进入三秒后 自己切换到News.vue
<template>
<div class="home">
<h2>海贼王真好看</h2>
</div>
</template>
<script setup lang="ts" name="Home">
import { onMounted } from 'vue';
import { useRouter } from 'vue-router';
const router=useRouter()
onMounted(()=>{
setTimeout(() => {
router.push('news')
}, 3000);
})
</script>
<style scoped>
h2{
margin-left: 45%;
}
</style>
如果我想点击查看详情的时候 出现详情信息
<template>
<div class="news">
<!-- 导航区 -->
<ul>
<li v-for="news in newsList" :key="news.id">
<button @click="show(news)">查看详情</button>
<RouterLink
:to="{
name:'xiang',
params:{
id:news.id,
name:news.name,
ability:news.ability
}
}">{{news.name}}</RouterLink>
</li>
</ul>
<div class="news-content">
<RouterView></RouterView>
</div>
</div>
</template>
<script setup lang="ts" name="News">
import router from '@/router';
import { reactive } from 'vue';
import { RouterView ,RouterLink,useRouter} from 'vue-router';
const router1=useRouter()
let newsList=reactive([
{id:'dadada1',name:'路飞',ability:'橡胶果实'},
{id:'dadada2',name:'白胡子',ability:'地震果实'},
{id:'dadada3',name:'黑胡子',ability:'暗暗果实'},
{id:'dadada4',name:'艾斯',ability:'炎炎果实'}
])
function show(news:any){
router1.push({
name:'xiang',
query:{
id:news.id,
name:news.name,
ability:news.ability
}
})
}
</script>
<style scoped>
/* 新闻列表容器样式 */
.news {
max-width: 600px;
margin: 0 auto;
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
/* 列表样式 */
.news ul {
list-style: none; /* 去掉默认的列表样式 */
padding: 0;
margin: 0;
}
/* 列表项样式 */
.news li {
margin-bottom: 10px; /* 添加间距 */
}
/* 链接样式 */
.news a {
display: block; /* 使链接占据整个列表项 */
padding: 10px;
text-decoration: none; /* 去掉下划线 */
color: #333; /* 文字颜色 */
border: 2px solid transparent; /* 默认无边框 */
border-radius: 5px; /* 圆角 */
transition: background-color 0.3s, border-color 0.3s; /* 平滑过渡效果 */
}
/* 链接悬停样式 */
.news a:hover {
background-color: #f0f0f0; /* 悬停时的背景颜色 */
border-color: #ccc; /* 悬停时的边框颜色 */
}
/* 链接激活样式(可选) */
.news a.active {
background-color: #333; /* 激活时的背景颜色 */
color: #fff; /* 激活时的文字颜色 */
border-color: #333; /* 激活时的边框颜色 */
}
</style>
重定向
{
path:'/',
redirect:'/about'
}