通过Vue路由传参的两种方式及Vue组件中接收参数的方式

1. Vue传参方式

1.1 通过动态路由传参

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:

1
2
3
4
5
6
7
8
9
10
const User = {
template: '<div>User</div>'
}

const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})

在这个实例中,我们就可以通过:id这种方式实现把参数的值传递到组件中,现在呢,像 /user/foo 和 /user/bar这样的路由,将把参数值foo、bar通过参数名id传递。

1.2 通过路由URL中添加query参数传参

通过路由URL中添加query参数的方式,就和普通的http URL的get传参方式一样,通过在链接地址后面添加?queryName=queryValue的方式实现传参,如:

1
2
3
4
5
6
7
8
9
10
const User = {
template: '<div>User</div>'
}

const router = new VueRouter({
routes: [
// 动态路径参数 以冒号开头
{ path: '/user/:id', component: User }
]
})

2. 组件中接收参数的方式

通过路由将参数传递后,我们需要在组件中进行接收,这样才可以在需要用到此参数的地方拿到对应的参数值,对应着两种传参方式,也分别有两种接收参数的形式。

2.1 通过this.$router.params接收

形如/user/:id这种的动态路由参数,我们可以通过this.$router.params接收,如在路由/user/:id中,在组件中拿到id的值的代码如下:

1
var id = this.$route.params.id;

2.2 通过this.$router.query接收

形如/search?q=vue这种的通过在链接地址后面添加?queryName=queryValue的方式实现传参的方式,我们可以通过this.$router.query接收,如在/search?q=vue中,在组件中拿到q的值的代码如下:

1
var q = this.$route.query.q;

2.3 将路由中的参数设置到组件的props上

上面两种接收参数的方式,都是通过$route对象来获取参数值的,然而在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。
因此,我们可以使用 props 将组件和路由解耦,用这种方式取代直接在组件中使用 $route 获取参数值的方式,代码示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const User = {
props: ['id'],
template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User, props: true },

// 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
{
path: '/user/:id',
components: { default: User, sidebar: Sidebar },
props: { default: true, sidebar: false }
}
]
})

这样你便可以在任何地方使用该组件,使得该组件更易于重用和测试。

这里需要注意的是,props设置有三种模式

  • 布尔模式
    如果 props 被设置为 true,route.params 将会被设置为组件属性。

    1
    2
    3
    4
    5
    const router = new VueRouter({
    routes: [
    { path: '/user/:id', component: User, props: true }
    ]
    })
  • 对象模式
    如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用。

    1
    2
    3
    4
    5
    const router = new VueRouter({
    routes: [
    { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
    ]
    })
  • 函数模式
    你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。

    1
    2
    3
    4
    5
    const router = new VueRouter({
    routes: [
    { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
    ]
    })

URL /search?q=vue 会将 {query: ‘vue’} 作为属性传递给 SearchUser 组件。