前提:下载安装
如果项目中有vue-router,并且已经完成了初步的配置,那么不需要进行这一步。
如果初始的vue中并没有vue-router,请往下完成添加:
1、在项目根目录打开终端输入命令,下载vue-router:
npm install vue-router@4
2、在项目的src目录下新建文件夹router,router文件夹内新建index.js:
3、index.js的基础内容如下:
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
]
})
export default router
4、在main.js或main.ts中全局挂载:
import router from './router'//导入router.js
app.use(router)//全局挂载使用
一、路由的基础用法
router-link
将被解析为一个带有正确 `href` 属性的 `<a>` 标签。
之所以不使用a标签,而是使用一个自定义组件来创建链接,是为了Vue Router 可以在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码。
router-view
作为路由的出口,路由匹配到的组件会被渲染的该位置上面。
可以适应自身的布局进行灵活跳转。
1、在app.vue中进行一个简单的布局:
<template>
<div class="container">
<div class="nav">
<ul>
<li><router-link to="/">首页</router-link></li>
<li><router-link to="/classify">分类</router-link></li>
<li><router-link to="/comic">漫画</router-link></li>
<li><router-link to="/world">世界</router-link></li>
<li><router-link to="/contribute">投稿</router-link></li>
<li><router-link to="/myop">开放平台</router-link></li>
</ul>
</div>
<div class="main">
<!-- 匹配路由的出口,将在此渲染 -->
<router-view></router-view>
</div>
<div class="footer">
XXX有限公司
</div>
</div>
</template>
<style>
.container {
width: 1200px;
margin: 0 auto;
}
.nav {
width: 100%;
height: 50px;
background-color: rgb(160, 160, 160);
display: flex;
justify-content: start;
align-items: center;
}
ul li {
float: left;
margin-right: 10px;
list-style: none;
text-decoration: none;
}
.main {
width: 100%;
min-height: 500px;
}
.footer {
width: 100%;
height: 100px;
background-color: rgb(160, 160, 160);
display: flex;
justify-content: center;
align-items: center;
}</style>
2、新建一些组件
组件的内容为:
3、对router>index.js的路由进行补充
index.js文件修改如下:
import { createRouter, createWebHistory } from 'vue-router'
import Classify from '../components/classify.vue'
import Comic from '../components/comic.vue'
import Contribute from '../components/contribute.vue'
import Myop from '../components/myop.vue'
import World from '../components/world.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
component: Classify
},
{
path: '/classify',
component: Classify
},
{
path: '/comic',
component: Comic
},
{
path: '/contribute',
component: Contribute
},
{
path: '/myop',
component: Myop
},
{
path: '/world',
component: World
},
]
})
export default router
4、对页面进行测试
对于上面的内容,我们已经完成了一个基本的配置路由,路由跳转的过程。但是路由的匹配规则,我们依然不清楚,接着往下学习。
二、带参数的动态路由匹配
将参数携带进url中,跳转页面后可解析出参数。
2.1、动态路由写法
router>index.js:
import { createRouter, createWebHistory } from 'vue-router'
import User from '../components/user.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
//前面加上冒号 代表参数
path: '/user/:id',
component: User
},
]
})
export default router
补充user.vue
组件通过$route.params来获取参数
user.vue
<template>
<h1>这里是用户界面</h1>
<p>页面参数为:{{ $route.params }}</p>
</template>
通过浏览器输入匹配的url测试
2.2、路由参数可以不止一个
我们将router>index.js修改一下:
import { createRouter, createWebHistory } from 'vue-router'
import User from '../components/user.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
//前面加上冒号 代表参数,这里有两个参数,分别为name、age
path: '/user/:name/:age',
component: User
},
]
})
export default router
测试一下:
2.3、响应路由参数的变化
当动态路由跳转,仅仅是参数改变。
例如:由/user/李四/23 跳转到 /user/张三/18
这种情况下,由于跳转的组件是同一个,因此没有必要对组件进行销毁重新创建。而是进行复用,这就意味着组件的生命周期构造函数不会被调用。
这种情况下,当路由参数改变时,我们想要做出相应的变化,可以使用侦听器。
user.vue:
<template>
<h1>这里是用户界面</h1>
<p>页面参数为:{{ $route.params }}</p>
<input type="text" v-model="name">
<input type="text" v-model="age">
<router-link :to="path">{{ path }}</router-link>
</template>
<script setup>
import { useRouter, useRoute } from 'vue-router'
import { watch, ref, computed } from 'vue'
//组合式中没有this,因此使用useRoute 这个api来代替this.$route
const route = useRoute();
const router = useRouter();
const name = ref('');
const age = ref('');
const path = computed(() => {
return "/user/" + name.value + "/" + age.value;
})
watch(
//监听路径
() => route.path,
(newValue, oldValue) => {
console.log('页面发生了跳转!新的参数:' + route.params.name + ':::' + route.params.age);
}
)
</script>
或者,使用 beforeRouteUpdate导航守卫
,它也可以取消导航。
导航守卫其实类似过滤器,拦截器,在跳转之前可以处理一些事情,如验证,取消跳转,改变跳转路径等。
三、路由的匹配语法
3.1、在参数中自定义正则
假设我们要跳转 /user/:id 这个路由,在组件创建的时候会携带id这个参数发送到后端获取用户的详细数据。
那么,一旦满足这个匹配规则就会发送一次请求到后端。但是我们心知肚明,我们的id是一个纯数字,如果路径变成了 /user/李四 ,我们就应该知道这是一个错误的路径。
这种情况我们可以给参数设置一个正则表达式,只有满足正则表达式的路径参数才能够访问到正确的组件。
给参数设置正则表达式。示例:
import { createRouter, createWebHistory } from 'vue-router'
import User from '../components/user.vue'
import NotFounted from '../components/notFound.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
//只匹配纯数字的路径参数
path: '/user/:id(\\d+)',
component: User
},
{
//匹配所有内容
path: '/:default(.*)*',
component: NotFounted
}
]
})
export default router
效果:
3.2、可重复的参数
我们还可以匹配多个部分的路由,例如/user/111/222/333。而组件所接收的参数为一个数字类型的数组。同样的,路径参数也可以进行正则匹配。
routes: [
{
//只匹配纯数字的路径参数
path: '/user/:id(\\d+)',
component: User
},
{
//匹配多个部分的路由
path: '/user/:id+',
component: User
},
{
//匹配所有内容
path: '/:default(.*)*',
component: NotFounted
}
]
3.3、路由配置:sensitive和strict
默认的路由不区分大小写,可以匹配尾部带斜线的路由。
例如: /user 可以匹配 /User /user/
我们可以通过sensitive(模糊匹配) 和strict(精准匹配)来进行控制。
routes: [
{
path: '/user/:id',
strict: true,//精准匹配
component: User
},
{
//匹配所有内容
path: '/:default(.*)*',
component: NotFounted
}
]
效果:/user/111 成功匹配
/user/111/ 匹配失败
3.4、可选参数:
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
//可选参数
path: '/user/:id(\\d+)?',
component: User
},
{
//匹配所有内容
path: '/:default(.*)*',
component: NotFounted
}
]