目录
基本创建步骤
下载vue-router的依赖:npm install vue-router@4
创建好路由组件,放在pages/views里面
(views
文件夹通常包含应用的页面。这些页面通常是与路由相对应的组件,代表应用的不同视图,components
文件夹通常包含可重用的组件。这些组件可以在多个视图中使用,通常是用于构建 UI 的小块)
在src下面创建一个router文件夹,新建index.ts或index.js
路径中加@与不加@的区别
路径的解析方式。
import Son01 from '@/components/Son01.vue';
:
@
是一个别名,通常在 Vue 项目中配置为指向src
目录。- 这种写法使得导入路径更简洁且易于管理。比如,如果你想导入
src/components/Son01.vue
,你可以使用@/components/Son01.vue
。- 别名
@
是在vue.config.js
或vite.config.js
等配置文件中进行配置的,确保在项目的构建工具中正确解析。
import Son01 from './components/Son01.vue';
:
./
表示相对路径,是从当前文件所在目录开始计算的路径。- 这种写法依赖于当前文件的相对位置,路径会随着文件结构的改变而改变。对于较深的文件夹结构,这种写法可能变得不够直观和方便。
总结:
- 使用
@
别名可以让路径更简洁,尤其是在大型项目中,路径管理和修改变得更容易。- 使用相对路径则更直接,但当项目结构发生变化时,维护相对路径可能会比较麻烦。
// 先引入createRouter
import { createRouter, createWebHistory } from 'vue-router'
// 引入组件
import Home from '@/components/Home.vue'
import News from '@/components/News.vue'
import About from '@/components/About.vue'
// 创建路由器
const router = createRouter({
history: createWebHistory(),
routes: [
// 以下是路由规则
{
path: '/home',
component: Home
},
{
path: '/news',
component: News
},
{
path: '/about',
component: About
},
]
})
// 暴露路由
export default router
history配置
1. Hash模式
- 定义:Hash模式使用URL中的哈希(#)部分来表示不同的路由。浏览器在处理哈希时不会重新加载页面。
- 优点:
- 简单易用,兼容性好,支持所有浏览器。
- 不需要服务器配置,直接在客户端处理。
- 缺点:
- URL不够美观,包含#符号。
- 不支持浏览器的历史记录管理(如前进、后退)。
示例:
http://example.com/#/home
2. History模式
- 定义:History模式利用HTML5的History API来管理路由,允许使用正常的URL而不需要哈希。
- 优点:
- URL更美观,用户体验更好。
- 支持浏览器的历史记录管理。
- 缺点:
- 需要服务器支持,必须配置服务器以处理所有路由请求。
- 对旧版浏览器的支持较差。
示例:
http://example.com/home
由于上面index.ts里面的export default router,路由暴露。
动态导入一个Vue组件
const routes = [
{
path: '/article/manage',
name: 'ArticleManage',
component: () => import('@/views/article/ArticleManage.vue')
}
];
-
该方式不要在文件最前面用import全部把路由组件导入,这样可以提升性能。
-
component
: 这是路由配置对象的一个属性,用于指定当前路由对应的组件。 -
() => import('@/views/article/ArticleManage.vue')
: 这是一个函数,当路由被访问时,这个函数会被调用。 -
import()
: 这是JavaScript的动态导入语法,用于按需加载模块。 -
@/views/article/ArticleManage.vue
: 这是模块路径,@
通常是在Vue项目中配置的别名,指向项目的src
目录。这里的路径指的是位于src/views/article
目录下的ArticleManage.vue
文件。 - 当用户访问与这个路由匹配的URL时,Vue Router会调用这个函数。
- 函数调用
import()
来动态地加载ArticleManage.vue
组件。 - 动态导入允许Webpack等构建工具进行代码分割(code splitting),这意味着
ArticleManage.vue
组件及其依赖的代码只会在需要时被加载,而不是在应用初始化时一次性加载所有代码。 - 这样可以减少应用的初始加载时间,提高性能。
接着在main.js里面去使用这个router
import { createApp } from 'vue'
import App from './App.vue'
// 引入路由器
import router from './router' // 默认会找该文件下的index
// 创建一个应用
const app = createApp(App)
// 使用路由
app.use(router)
// 挂在到整个app容器里面,index.html里面的id="app"
app.mount('#app')
至此,就完全搭建好了路由的环境,接下来就到App.vue里面去使用(style省略)
引入RouterView ,RouterLink,设置显示路由展示区,以及跳转
<script setup>
<!-- 从vue-router引入RouterView ,RouterLink -->
import { RouterView ,RouterLink} from 'vue-router';
</script>
<template>
<nav class="navbar">
<div class="logo" style="display: inline-block;">
<RouterLink to="/home"><img src="./相机图标.webp" alt="log" width="40px"></RouterLink>
</div>
<div class="links" style="display: inline-block;">
<RouterLink to="/home">首页</RouterLink>
<RouterLink to="/news">新闻</RouterLink>
<RouterLink to="/about">关于</RouterLink>
<!-- RouterLink标签相当于a标签,来跳转 -->
</div>
</nav>
<!-- 路由展示区 -->
<div>
<RouterView></RouterView>
</div>
</template>
to的两种写法:
- :to="{path:/about} " 或 :to="{name:'guanyu'}"(在routes里加了name) (v-bind和对象的形式)
- to="/about"
子级路由的引入
在index.ts里面的父级组件news加上children,同样添加路由属性
{
path: '/news',
component: News,
children:[
{
path:'detal', // 子级不写‘/’
component:detail
}
]
},
news组件里引入import { RouterLink, RouterView } from 'vue-router';
注意:to="/news/detail"
<!-- script里引入import { RouterLink, RouterView } from 'vue-router'; -->
<div>
<ul>
<li v-for="news in newsArticles" :key="news.id">
<RouterLink to="/news/detail">{{ news.name }}</RouterLink>
<span class="views">点击量:{{ news.views }}</span>
</li>
</ul>
</div>
<!-- 新闻展示区 -->
<RouterView></RouterView>
<div>
路由的传参
query参数
父级组件中向子组件传参:
- 方法一
<RouterLink :to="`/news/detail?title=${news.name}&content=${news.content}`">{{ news.name }}</RouterLink>
- 方法二
<RouterLink :to="{
path:'/news/detail', // 跳转到的子级组件
// name:"neirong",name参数也可以
query:{ // 向组件里传的参数
title:news.name,
content:news.content
}
}">{{ news.name }}</RouterLink>
父组件传完参数后,在子组件里展示
<template>
<ul>
<li>标题:{{ route.query.title }}</li>
<li>内容:{{ route.query.content }}</li>
</ul>
</template>
<script setup>
import { useRoute } from 'vue-router';
const route = useRoute()
console.log(route); // 这个route参数里面有父组件传过来的数据
</script>
params参数
在index.ts文件中改path值为:path:'detail/:Title/:Content'
为参数占位;如果有可传可不传的参数,就在参数后面加’?‘且对象数组中值为undefined
显示为:
children:[
{
name:"juti",
path:'detail/:Title/:Content', // 这几个参数Title等之后传到子级组件
// Detail里
// path:'detail/:Title?/:Content' 如果有的参数可传可不传,就在参数后面加‘?’,
// 然后使用params对象传参
component:Detail
}
]
在父组件里面
<RouterLink :to="`/news/detail/${ news.name }/${ news.content }`">{{ news.name }}</RouterLink>
也可以通过params列表传对象,但path不能传,要改为传name,因为params只能和name一起用
<RouterLink
:to="{
name:'juti', // 不能写path
params:{ // params不能传对象或数组
Title:news.name, // 没有标题原新闻对象数组里会写undefined
Content:news.content
}
}">={{ news.name }}
</RouterLink>
子组件中
<template>
<ul>
<li>标题:{{ route.params.Title }}</li>
<li>内容:{{ route.params.Content }}</li>
</ul>
</template>
<script setup>
import { useRoute } from 'vue-router';
const route = useRoute()
console.log(route);
</script>
设置路由的props配置传参
在index.ts里面配置props
{
name:"juti",
path:'detail/:Title?/:Content', // 子级不写‘/’
component:Detail,
props:true // 这样就可以在路由中进行props传参了
}
在父组件里面保证是params参数,params就会是为props参数,这样在子组件里就可以不用useRoute(params和props一起打辅助)
<template>
<ul>
<li>标题:{{ Title }}</li>
<li>内容:{{ Content }}</li>
</ul>
</template>
<script setup>
// import { useRoute } from 'vue-router';
// const route = useRoute()
// console.log(route);
defineProps(['Title', 'Content'])
</script>
replace和push
<RouterLink replace></RouterLink> // 直接在RouterLink标签里加
<RouterLink push></RouterLink>
push
:会向浏览器的历史记录栈添加一个新的记录。这意味着如果你使用push
导航到新路由,用户可以使用浏览器的“后退”按钮返回到之前的路由。replace
:不会向历史记录栈添加新记录,而是替换当前的路由记录。这意味着使用replace
后,用户无法通过“后退”按钮【<=】返回到之前的路由。
编程式路由导航
即脱离RouterLink实现跳转。(比如跳出广告--->用onMounted:页面加载时打开小页面)
import { useRouter } from 'vue-router'; // 引入useRouter
const router = useRouter()
// 以下是跳转函数
const checknews = (news) => {
router.push({
name:'juti',
params:{
Title:news.name,
Content:news.content
}
})
}
<li v-for="news in newsArticles" :key="news.id">
<button @click="checknews(news)">查看</button>
</li>
重定向
即在routes数组里加上:
{
path:'/',
redirect:'/home'
}
实现一进页面跳转到默认页面,即确定首页
routes: [
// 以下是路由规则
{
path: '/home',
component: Home
},
{
path: '/news',
component: News,
children:[
{
name:"juti",
path:'detail/:Title?/:Content', // 子级不写‘/’
component:Detail,
props:true
}
]
},
{
name:'guanyu',
path: '/about',
component: About
},
// 下面是重定向
{
path:'/',
redirect:'/home'
}
]