Vue-router:6、动态路由匹配
6.1 动态匹配路由的基本用法
思考:
<!– 有如下 3 个路由链接 -->
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
// 定义如下三个对应的路由规则,是否可行???
{ path: '/user/1', component: User }
{ path: '/user/2', component: User }
{ path: '/user/3', component: User }
虽然以上规则可以匹配成功,但是这样写比较麻烦。如果有100个规则,那么写起来就会非常的麻烦。
通过观察,可以发现整个路由规则中只有后续的数字是在变化的。所以这里可以通过动态路由参数的模式进行路由匹配。
var router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})
const User = {
// 路由组件中通过$route.params获取路由参数
template: '<div>User {{ $route.params.id }}</div>'
}
具体代码实现如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<!-- 导入 vue 文件 -->
<!-- <script src="./lib/vue_2.5.22.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- <script src="./lib/vue-router_3.0.2.js"></script> -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<!-- 被 vm 实例所控制的区域 -->
<div id="app">
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
template: '<h1>User 组件 -- 用户id为: {{$route.params.id}}</h1>'
}
const Register = {
template: '<h1>Register 组件</h1>'
}
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user'},
{ path: '/user/:id', component: User },
{ path: '/register', component: Register }
]
})
// 创建 vm 实例对象
const vm = new Vue({
// 指定控制的区域
el: '#app',
data: {},
// 挂载路由实例对象
// router: router
router
})
</script>
</body>
</html>
6.2 路由组件传递参数
$route
与对应路由形成高度耦合,不够灵活,所以可以使用props
将组件和路由解耦
第一种情况:
props的值为布尔类型
const router = new VueRouter({
routes: [
// 如果 props 被设置为 true,route.params 将会被设置为组件属性
{ path: '/user/:id', component: User, props: true }
]
})
const User = {
props: ['id'], // 使用 props 接收路由参数
template: '<div>用户ID:{{ id }}</div>' // 使用路由参数
}
在定义路由规则的时候,为其添加了props
属性,并将其值设置为true
.那么在组件中就可以通过props:['id']
的形式来获取对应的参数值。
具体代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<!-- 导入 vue 文件 -->
<script src="./lib/vue_2.5.22.js"></script>
<script src="./lib/vue-router_3.0.2.js"></script>
</head>
<body>
<!-- 被 vm 实例所控制的区域 -->
<div id="app">
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
props: ['id'], //获取id的值。
template: '<h1>User 组件 -- 用户id为: {{id}}</h1>'
}
const Register = {
template: '<h1>Register 组件</h1>'
}
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user'},
//将props设置为true.
{ path: '/user/:id', component: User, props: true },
{ path: '/register', component: Register }
]
})
// 创建 vm 实例对象
const vm = new Vue({
// 指定控制的区域
el: '#app',
data: {},
// 挂载路由实例对象
// router: router
router
})
</script>
</body>
</html>
第二种情况: props
的值为对象类型
const router = new VueRouter({
routes: [
// 如果 props 是一个对象,它会被按原样设置为组件属性
//这里相当于给组件User,通过路由的形式传递了一个对象,而这时候id在User组件中就无法获取到了。
{ path: '/user/:id', component: User, props: { uname: 'lisi', age: 12 }}
]
})
const User = {
props: ['uname', 'age'],
template: ‘<div>用户信息:{{ uname + '---' + age}}</div>'
}
具体代码实现如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<!-- 导入 vue 文件 -->
<!-- <script src="./lib/vue_2.5.22.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- <script src="./lib/vue-router_3.0.2.js"></script> -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<!-- 被 vm 实例所控制的区域 -->
<div id="app">
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
props: ['id', 'uname', 'age'],
template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
}
const Register = {
template: '<h1>Register 组件</h1>'
}
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user'},
{ path: '/user/:id', component: User, props: { uname: 'lisi', age: 20 } },
{ path: '/register', component: Register }
]
})
// 创建 vm 实例对象
const vm = new Vue({
// 指定控制的区域
el: '#app',
data: {},
// 挂载路由实例对象
// router: router
router
})
</script>
</body>
</html>
在上面的代码中,在路由规则中,通过props
向用户组件中传递了一个对象,那么在User
用户组件中可以接收到传递过来的对象。但是参数id
无法接收到。
如果要解决这个问题,可以使用props
的值为函数类型。也就是给props
传递一个函数。
第三种情况:props
的值为函数类型
const router = new VueRouter({
routes: [
// 如果 props 是一个函数,则这个函数接收 route 对象为自己的形参
//route就是参数对象。
{ path: '/user/:id',
component: User,
props: route => ({ uname: 'zs', age: 20, id: route.params.id })}
]
})
const User = {
props: ['uname', 'age', 'id'],
template: ‘<div>用户信息:{{ uname + '---' + age + '---' + id}}</div>'
}
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<!-- 导入 vue 文件 -->
<!-- <script src="./lib/vue_2.5.22.js"></script> -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- <script src="./lib/vue-router_3.0.2.js"></script> -->
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<!-- 被 vm 实例所控制的区域 -->
<div id="app">
<router-link to="/user/1">User1</router-link>
<router-link to="/user/2">User2</router-link>
<router-link to="/user/3">User3</router-link>
<router-link to="/register">Register</router-link>
<!-- 路由占位符 -->
<router-view></router-view>
</div>
<script>
const User = {
props: ['id', 'uname', 'age'],
template: '<h1>User 组件 -- 用户id为: {{id}} -- 姓名为:{{uname}} -- 年龄为:{{age}}</h1>'
}
const Register = {
template: '<h1>Register 组件</h1>'
}
// 创建路由实例对象
const router = new VueRouter({
// 所有的路由规则
routes: [
{ path: '/', redirect: '/user' },
{
path: '/user/:id',
component: User,
props: route => ({ uname: 'zs', age: 20, id: route.params.id })
},
{ path: '/register', component: Register }
]
})
// 创建 vm 实例对象
const vm = new Vue({
// 指定控制的区域
el: '#app',
data: {},
// 挂载路由实例对象
// router: router
router
})
</script>
</body>
</html>