一、背景
我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 My组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们需要 vue-router实现动态路由的效果。

二、动态路由
2.1 完整实现
编写一个路由配置表,不同的URL对应不同的组件
router/index.js
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'
import My from '@/views/My.vue'
import MyProfile from '@/views/MyProfile.vue'
const routes = [
{
path: '/home',
name: 'home',
component: Home
},
{
path: '/about',
name: 'about',
component: About
},
{
path: '/my/:id',
name: 'my',
component: My,
props:true,
children:[
{
// 当 /My/:id/profile 匹配成功,
// MyProfile 会被渲染在 My 的 <router-view> 中
path:"profile",
component:MyProfile
}
]
},
{
path: '/',
component: Home
},
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router
Home组件
<template>
<div>
<h2>主页</h2>
<!-- 使用 router-link 组件来导航. -->
<router-link to="/about">关于</router-link>
</div>
</template>
About组件
<template>
<div>
<h2>关于</h2>
<!-- 使用 router-link 组件来导航. -->
<router-link to="/home">首页</router-link>
</div>
</template>
My组件
<!-- 视图层: html -->
<template>
<div>
<h2>我的</h2>
<p>欢迎回来:{{ userId }}</p>
<router-view></router-view>
<router-link to="/home">首页</router-link>
</div>
</template>
<!-- 逻辑层:js -->
<script>
// vue基础-插值表达式
export default {
// 组件名称
name: "",
data() {
return {
userId: "",
};
},
mounted() {
// 挂载时参数值会被设置到 this.$route.params
this.userId = this.$route.params.id;
},
};
</script>
<style lang="less">
</style>
MyProfile组件
<!-- 视图层: html -->
<template>
<div>
{{ myProfile }}
</div>
</template>
<!-- 逻辑层:js -->
<script>
// vue基础-插值表达式
export default {
// 组件名称
name: "",
data() {
return {
list: [
{ id: "123", name: "Mike", sex: "男", age: 16 },
{ id: "456", name: "Rose", sex: "女", age: 19 },
],
myProfile: null,
};
},
// 定义和用法
// find() 方法返回通过测试(函数内判断)的数组的第一个元素的值。
// find() 方法为数组中的每个元素都调用一次函数执行:
// 当数组中的元素在测试条件时返回 true 时, find() 返回符合条件的元素,之后的值不会再调用执行函数。
// 如果没有符合条件的元素返回 undefined
// 注意: find() 对于空数组,函数是不会执行的。
// 注意: find() 并没有改变数组的原始值。
created() {
this.myProfile = this.list.find((x) => x.id == this.$route.params.id);
},
};
</script>
<style lang="less">
</style>
提供一个路由占位,用来挂载URL匹配到的组件
App.vue
<template>
<div id="app">
<h1>使用vue-router实现动态路由</h1>
<hr />
</div>
<!-- 路由出口 -->
<router-view />
</template>
<style lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>
运行测试


