这一节了解一下Vue3中的路由知识,Vue3路由是指为单页应用程序提供导航功能的机制。它允许用户在不重新加载整个页面的情况下,通过URL的变化来动态更新页面的一部分内容。其核心原理是通过监听URL的变化,根据预先配置的路由表(路径与组件的映射关系),动态地将对应的组件渲染到<router-view>容器中。简单总结如下:
API:
1 创建路由实例
javascript
import {createRouter, createWebHashHistory} from "vue-router"
const router = createRouter({
history: createWebHashHistory(),
routes: []
})
2 注册路由到Vue应用
javascript
const app = createApp(App)
app.use(router)
app.mount("#app")
3 <router‑link>页面跳转组件
javascript
<router-link to="/demo1">页面1</router-link>
4 <router‑view>路由出口,渲染匹配组件
javascript
<router-view></router-view>
5 静态路由配置
javascript
const routes = [
{path:"/demo1", component: Demo1}
]
6 动态路由参数 `:参数名`,$route.params 获取
javascript
//路由
{path:"/user/:username/:id", component:User}
//组件获取
$route.params.username
$route.params.id
7 可选路由参数"?"
javascript
{path:"/user/:username?", component:User}
8 多级通配参数"*",参数转为数组
javascript
{path:"/category/:cat*", component:Category}
//访问 /category/a/b/c → params.cat = ["a","b","c"]
9 同组件参数更新触发 beforeRouteUpdate
javascript
export default {
beforeRouteUpdate(to, from){
//参数变更业务逻辑
}
}
10 嵌套路由 children 配置,子组件需要内部 router‑view 出口
javascript
{
path:"/user",
component:User,
children:[{path:"friends/:count", component:Friends}]
}
11 命名路由 name 属性,跳转使用 name+params,避免硬编码 url
javascript
const routes = [{name:"user", path:"/user/:id", component:User}]
//跳转
this.$router.push({name:"user", params:{id:100}})
12 命名视图:多个同级 router‑view,使用 components 对象
javascript
<!--模板多个命名出口-->
<router-view name="topBar"></router-view>
<router-view name="main"></router-view>
javascript
//路由配置
{
path:"/home",
components:{
topBar: User,
main: UserSetting
}
}
13 路由重定向redirect,支持函数动态重定向
javascript
//静态
{path:"/d/1", redirect:"/demo1"}
//动态函数
{path:"/d", redirect:(to)=>{ return {path:"/demo2"}}}
14 push ():新增 history 历史栈,可以浏览器回退
javascript
this.$router.push("/user/小王")
this.$router.push({name:"user", params:{username:"小王"}})
this.$router.push({path:"/user", query:{name:"xixi"}})
15 replace ():替换当前历史记录,不新增栈,无法回退上一页
javascript
this.$router.replace({path:"/user"})
16 路由 props 解耦,去除组件对 $route 依赖(布尔 / 对象 / 函数三种模式)
javascript
//模式1 props:true params映射组件props
{path:"/user/:id", component:UserSetting, props:true}
//模式2 对象,固定传参
{path:"/user/:id", component:UserSetting, props:{id:"000"}}
//模式3 函数动态返回属性
{path:"/user/:id", component:UserSetting, props:(route)=>{return {id:route.params.id}}}
17 全局前置守卫 beforeEach,拦截所有路由跳转,可拦截 / 重定向
javascript
router.beforeEach((to,from)=>{
if(!isLogin) return {path:"/login"}
return true //放行
})
18 全局后置守卫 afterEach,仅监控,不能拦截跳转
javascript
router.afterEach((to,from,failure)=>{
console.log("路由完成跳转")
})
19 路由独享守卫 beforeEnter,仅进入路由触发,参数更新不触发
javascript
{path:"/demo1", component:Demo1, beforeEnter:(to)=>{return true}}
20 addRoute () 运行时动态注册路由
javascript
this.$router.addRoute({path:"/demo2", component:Demo2})
21 removeRoute /hasRoute/getRoutes 路由删除与查询
javascript
this.$router.removeRoute("Demo2") //按name删除路由
this.$router.hasRoute("Demo2") //判断路由是否注册
this.$router.getRoutes() //获取全部路由数组
栗子:
javascript
1. components/Demo1.vue
<template>
<h1>示例页面1</h1>
</template>
<script>
export default {
}
</script>
javascript
2. components/Demo2.vue
<template>
<h1>示例页面2</h1>
</template>
<script>
export default {
}
</script>
javascript
3. App.vue
<template>
<h1>Vue Router Demo</h1>
<p>
<router-link to="/demo1">跳页面一</router-link>
<br/>
<router-link to="/demo2">跳页面二</router-link>
</p>
<!--路由出口-->
<router-view></router-view>
</template>
<script>
export default {
name:"App"
}
</script>
javascript
4. main.js
import { createApp } from 'vue'
import { createRouter, createWebHashHistory } from 'vue-router'
import App from './App.vue'
import Demo1 from './components/Demo1.vue'
import Demo2 from './components/Demo2.vue'
//路由配置
const routes = [
{ path:'/demo1', component: Demo1 },
{ path:'/demo2', component: Demo2 }
]
//创建路由实例
const router = createRouter({
history: createWebHashHistory(),
routes
})
const app = createApp(App)
app.use(router)
app.mount('#app')
javascript
1. components/User.vue
<template>
<h1>用户中心</h1>
<h2>用户名:{{ username }}</h2>
<h2>用户ID:{{ id }}</h2>
</template>
<script>
export default {
//通过props接收路由参数,解耦$route
props:["username","id"],
beforeRouteUpdate(to, from){
alert(`参数更新:新用户名${to.params.username}, id:${to.params.id}`)
}
}
</script>
javascript
2. App.vue
<template>
<h1>动态路由 Demo</h1>
<p>
<router-link to="/user/张三/1001">张三(1001)</router-link>
<br>
<router-link to="/user/李四/1002">李四(1002)</router-link>
</p>
<router-view></router-view>
</template>
<script>
export default {name:"App"}
</script>
javascript
3. main.js
import { createApp } from 'vue'
import { createRouter, createWebHashHistory } from 'vue-router'
import App from './App.vue'
import User from './components/User.vue'
const routes = [
{
path:"/user/:username/:id",
component:User,
props:true // 将params映射为组件props属性
}
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
const app = createApp(App)
app.use(router)
app.mount("#app")
注意:
1 版本严格匹配:Vue3项目必须使用vue-router@4,Vue2项目使用vue-router@3,两者混用会导致报错。
2 动态路由传参规范:在使用params传参时,必须搭配name(命名路由)使用,不能与path混用,否则参数会被忽略导致丢失。
3 动态路由注册顺序:在动态添加路由(addRoute)时,必须先添加父路由,再添加子路由,否则子路由可能无法生效。