在组件中可以通过路由进行跳转,在跳转的同时可以传递一些参数
更多精彩
- 更多技术博客,请移步 IT人才终生实训与职业进阶平台 - 实训在线
官方提供的解决方案
- 路由组件传参 | Vue Router
- 上述链接就是官方对于路由组件传参的解决方案,分别为
- 布尔模式
- 对象模式
- 函数模式
简单易懂的布尔模式
- 就是在指定路由的配置中添加
props: true
,那么子组件就可以识别父组件在链接中携带的参数 - 例如在 router.js 中指定如下配置
const router = new VuewRouter({
routes: [
path: '/knowledge/:id',
component: resolve => require(['views/knowledge/form'], resolve),
props: true
]
})
- 同时在子组件中添加
props: {
id: {
type: String,
default: '0'
}
}
- 那么当父组件通过
/knowledge/1
跳转到子组件时,在子组件中执行console.log(this.id)
,输出结果就会是 1 - 如果 router.js 中对应路由没有添加
props: true
,在子组件中执行的结果则是 0
易于扩展的函数模式
- 相对于简单易懂的布尔模式,函数模式的优势则是易于扩展
- 假设存在一个场景:父组件在向子组件跳转时,可能传参,也可能不传参,这个时候应该如果定义路由格式
布尔模式的局限性
- 如果用布尔模式,由于参数是被拼接在组件之间的请求链接上,所以就算父组件向子组件跳转时不需要传参,为了保证能跳转成功,也必须传递一个默认值,否则路由将无法正确识别到指定的子组件
- 例如父子组件之间跳转的请求链接是
/knowledge/:id
,那么父组件在向子组件跳转时,不论有没有对应的 id 需要传递,都必须在跳转链接上携带一个值,以确保链接能被正确识别 - 如果将 0 作为一个无意义的值,则是在需要传参时使用
/knowledge/1
,在不需要传参时使用/knowledge/0
函数模式的优势
- 如果使用函数模式,则可以有效避免上述情况,在 router.js 中指定如下配置
const router = new VuewRouter({
routes: [
path: '/knowledge',
component: resolve => require(['views/knowledge/form'], resolve),
props: (route) => ({
id = route.query.id
})
]
})
- 子组件中依旧添加
props: {
id: {
type: String,
default: '0'
}
}
- 那么当父组件要跳转到子组件,同时需要携带参数时,通过
/knowledge?id=1
即可 - 当父组件要跳转到子组件,却不需要传递参数时,通过
/knowledge
即可
函数模式容易被误会的劣势
- 你可能会想到,那么如果有多个参数需要传递
- 使用布尔模式只需要
/knowledge/:id/:pid/:sid
即可,同时在子组件指定对应的props
即可完成接收 - 使用函数模式则不仅要在子组件完成相同的操作,还需要在 router.js 中指定如下配置
const router = new VuewRouter({
routes: [
path: '/knowledge',
component: resolve => require(['views/knowledge/form'], resolve),
props: (route) => ({
id = route.query.id,
pid = route.query.pid,
sid = route.query.sid
})
]
})
- 其实不然,如果有多个参数,利用 ES6 的特性,函数模式传参可以简写为如下格式
- 只需要按照如下格式编写,就会自动将
route.query
中所有的参数都解耦为上述格式
- 只需要按照如下格式编写,就会自动将
const router = new VuewRouter({
routes: [
path: '/knowledge',
component: resolve => require(['views/knowledge/form'], resolve),
props: (route) => route.query
]
})
布尔模式和函数模式的混用
- 布尔模式和函数模式其实都很好,小孩子才做选择,成年人自然是两个都想要,那么怎么做呢?
- 如果在 router.js 中指定如下配置
const router = new VuewRouter({
routes: [
path: '/knowledge/:id',
component: resolve => require(['views/knowledge/form'], resolve),
props: (route) => ({
pid = route.query.pid
})
]
})
- 那么在父组件中通过
/knowledge/1?pid=2
跳转到子组件,是否可以同时拿到id
和pid
呢? - 答案是不行,只能顺利拿到
pid
,因为启用布尔模式的前提是props: true
,而这里的props
已经被用来接收函数了 - 成年人显然不高兴了,必须想办法两个都拿到,其实只要将配置改为如下格式即可
const router = new VuewRouter({
routes: [
path: '/knowledge/:id',
component: resolve => require(['views/knowledge/form'], resolve),
props: (route) => ({
id = route.params.id,
pid = route.query.pid
})
]
})
- 只需要这样,通过
/knowledge/1?pid=2
就可以同时拿到id=1
以及pid=2
了
混用模式的精简版
- 都已经做到这一步了,可能那些有代码洁癖的家伙还是会不高兴
- 因为如果有多个链接参数,和多个可选参数,例如以下配置,岂不是显得更加繁琐
const router = new VuewRouter({
routes: [
path: '/knowledge/:id/:sid',
component: resolve => require(['views/knowledge/form'], resolve),
props: (route) => ({
id = route.params.id,
sid = route.params.sid,
pid = route.query.pid,
mid = route.query.mid
})
]
})
- 对于上述窘境,我们可以简单分析一下,路由组件的传参的函数模式,其实就是表示
props
可以接收一个函数 - 而函数中其实使用的是一个被封装后的对象,所以我们才能将函数模式精简为
props: (route) => route.query
- 那么
route.params
和route.query
其实就是两个对象,只要将这两个对象合并成一个对象不就可以了吗? - 这个时候就需要使用 Lodash 的 Merge 函数,进行如下修改
const router = new VuewRouter({
routes: [
path: '/knowledge/:id/:sid',
component: resolve => require(['views/knowledge/form'], resolve),
props: (route) => _.merge(route.params, route.query)
]
})
网友评论