目录
路由组件传参
我们在开发单页面应用时,有时需要进入某个路由后基于参数从服务器获取数据,那么我们首先要获取路由传递过来的参数,从而完成服务器请求,所以,我们需要了解路由传参的几种方式。
编程式路由传参
除了使用 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。
通过 params 传递
路由配置,路径参数用冒号 :
表示。
const routes = [
// 动态段以冒号开始
{path: 'goods/:id', name: "goods", component: Goods},
]
router.push()
方法的参数可以是一个字符串路径,或者一个描述地址的对象。
<script>
export default {
name: 'App',
methods: {
linkToGoods() {
// 字符串
this.$router.push('/goods/1')
// 对象
this.$router.push({path: '/goods/1'})
// 命名的路由
this.$router.push({name: 'goods', params: {id: 1}})
},
}
}
</script>
组件获取数据,当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params
的形式暴露出来。
<template>
<div>
<h2>商品 {{ $route.params.id }}</h2>
</div>
</template>
<script>
export default {
name: 'goods',
}
</script>
通过 query 传递
这种情况下 query
(查询参数)传递的参数会显示在 url 后面,如: /goods/1?from=tb
。
路由配置,使用 query
时,以下三种方式都是可行的:
<script>
export default {
name: 'App',
methods: {
linkToGoods() {
this.$router.push('/goods/1?from=tb')
this.$router.push({path: '/goods/1', query: {from: "tb"}})
this.$router.push({name: 'goods', params: {id: 1}, query: {from: "tb"}})
},
}
}
</script>
组件通过 $route.query
获取:
<template>
<div>
<h2>商品 {{ $route.query.from }}</h2>
</div>
</template>
<script>
export default {
name: 'goods',
}
</script>
通过 hash 传递
通过此方式,url 路径中带有 hash
,例如: /goods/1#tb
。
路由配置,使用 hash
时,以下三种方式都是可行的(同 query
):
<script>
export default {
name: 'App',
methods: {
linkToGoods() {
this.$router.push('/goods/1#tb')
this.$router.push({path: '/goods/1', hash: "#tb"})
this.$router.push({name: 'goods', params: {id: 1}, hash:"#tb"})
},
}
}
</script>
组件通过 $route.hash.slice(1)
获取:
<template>
<div>
<h2>商品 {{ $route.hash.slice(1) }}</h2>
</div>
</template>
<script>
export default {
name: 'goods',
}
</script>
通过 props 进行传递
在组件中使用 $route
会与路由紧密耦合,这限制了组件的灵活性,因为它只能用于特定的 URL。虽然这不一定是件坏事,但我们可以通过 props
配置来解除这种行为。
以解耦的方式使用 props
进行参数传递,主要是在路由配置中进行操作。
布尔模式
当 props
设置为 true
时, route.params
将被设置为组件的 props。
例如下面的代码是通过 $route
的方式获取动态字段 id
:
const routes = [{path: '/goods/:id', name: "goods", component: Goods}]
<template>
<div>
<h2>商品 {{ $route.params.id }}</h2>
</div>
</template>
将上面的代码替换成 props
的形式,如下:
// 路由配置中,增加 props 字段,并将值设置为 true
const routes = [{path: '/goods/:id', name: "goods", component: Goods, props: true}]
<template>
<div>
<!-- 组件中通过 props 获取 id -->
<h2>商品 {{ id }}</h2>
</div>
</template>
注意:对于有命名视图的路由,你必须为每个命名视图定义 props
配置:
对象模式
当 props
是一个对象时,它将原样设置为组件 props
。当 props
是静态的时候很有用。
const routes = [{path: '/goods', name: "goods", component: Goods, props: {id: 1}}]
template>
<div>
<h2>商品 {{ id }}</h2>
</div>
</template>
<script>
export default {
name: 'goods',
props: {
id: {
type : Number,
default: 0
}
}
}
</script>
组件默认显示 商品 0
,但路由配置了 props 对象,当路由跳转到 /goods
传递过来的 id
, 页面会显示为 商品 1
。
函数模式
可以创建一个返回 props 的函数。这允许你将参数转换为其他类型,将静态值与基于路由的值相结合等等。
路由配置,使用函数模式时,返回 props 的函数接受的参数为路由记录 route
。
const routes = [
{
path: '/goods',
name: "goods",
component: Goods,
props: route => ({query: route.query.q})
}
]
当 URL 为 /goods?q=vue
时, 将传递 {query: 'vue'}
作为 props 传给 Goods
组件。
<template>
<div>
<h2>商品 {{ query }}</h2>
</div>
</template>
<script>
export default {
name: 'goods',
props: {
query: {
type : String
}
}
}
</script>
注意:请尽可能保持
props
函数为无状态的,因为它只会在路由发生变化时起作用。如果你需要状态来定义 props,请使用包装组件,这样 vue 才可以对状态变化做出反应。