Vue-router: Pass data to component from route

Created on 7 Mar 2016  ·  14Comments  ·  Source: vuejs/vue-router

It would be nice if it was possible to pass arbitrary data to a component via a data object.

this.$router.go({name: '/signout', data: {message: 'Token expired'}});

Which would then be available to the component in the usual format.

Most helpful comment

I'm in general against this type of ad-hoc data passing - it's better to manage the state explicitly somewhere (e.g. in a store)

All 14 comments

I'm in general against this type of ad-hoc data passing - it's better to manage the state explicitly somewhere (e.g. in a store)

I would like to reopen this feature-request,

I am making a CSS Documentation, the documents should share the same components,

cause documents all look the same, but I cannot pass data fromvue-router to component,

so what I can only do is like this:

2016-08-30 3 33 03

but If I can pass the data from router to components,

I can use it like the following paths without creating new components with the same contents but just require different datas.

2016-08-30 3 33 59

@YamiOdymel Why not store the data into the meta key?

Passing this kind of data in the route object defeats the purpose of a router: That the URL should determine the state of the application.

If you pass this data in the route object, your application will error out (or behave differently) when you enter /element/container directly (so the data in the route is missing), versus when you navigate there from another view (which has set the data in the route).

So this should be avoided, and rather, state should be inferred from the URL alone:

{
path: '/elements/:elementType',
component: require(../views/Doc)
}

use the param to render the correct component..

<template>
  <component :is="$route.prarams.elementType"></component>
</template>

...or get the correct items in the component or whatever you need.

Hi guys,

I have similar question,
Is it possible to pass additional 'static' params to component?, for example I have routes:

{ name: 'news',  path: '/news/:id?', component: require('./page')},
{ name: 'articles',  path: '/articles/:id?', component: require('./page')},
{ name: 'other',  path: '/:othertype/:id?', component: require('./other')}

and as result I have to pass (somehow) page type (news or articles) to 'page' component

I thought it could be solved as (due to order priority)

{ name: 'page',  path: '/:pagetype/:id?', component: require('./page')},
{ name: 'other',  path: '/:othertype/:id?', component: require('./other')}

but as result 'page' component will catch all required routes

Is it possible?

{ name: 'news',  path: '/news/:id?', params: {type:'news'}, component: require('./page')}

or something like

{ name: 'news',  path: '/:type(articles|news)/:id?', component: require('./page')},
{ name: 'other',  path: '/:othertype/:id?', component: require('./other')}

If I understood well, you can use the new props feature: https://github.com/vuejs/vue-router/blob/dev/docs/en/essentials/passing-props.md
Next time, please, ask questions in the forums 🙂

Please refer to the documentation about meta data in route definitions.

@posva, @LinusBorg Thanks a lot!
both 'meta' and 'props' can solve my problem,
but passing 'props' is exactly for my case )

I will use forums next time :slightly_smiling_face:

I believe there should be a mechanism which allows you to pass data into a route. It's up to you to implement the fallback if the route was navigated to directly.

Consider a list of users, /users. Now you open a single user profile, /users/:id. Since you were on the page /users, you already have the data needed for the page /users/:id. As you cannot pass data to a route you're navigating to, now you have to do the API call again, even though the data is actually in the memory.

If we could send data through the router (basically what meta is now, just not configuration-time, but dynamic during run-time), we could ask if that data is defined and use it. If it's not, we do the API call (that's the case when a user navigates directly to /users/:id by typing that in the browser).

OP's usecase is also not uncommon. There is a page, it exists on its own, but based on where you're coming from it _can_ look a little bit different than coming straight to the URL.

Consider a list of users, /users. Now you open a single user profile, /users/:id. Since you were on the page /users, you already have the data needed for the page /users/:id. As you cannot pass data to a route you're navigating to, now you have to do the API call again, even though the data is actually in the memory.

that's what state management solutions like vuex are for. This does not fall into the domain and responsibility of the router.

If we could send data through the router (basically what meta is now, just not configuration-time, but dynamic during run-time), we could ask if that data is defined and use it. If it's not, we do the API call (that's the case when a user navigates directly to /users/:id by typing that in the browser).

or just:

  • dispatch a GET_USER action to vuex in both cases, which will check weither the user already exists
  • if he does, it does nothing
  • if he doesn't, it will do the ajax call
  • then add the getter for the current user to your component and it will receive the user not matter where it came from.

That would be the clean, maintainable way to do it, in our view. So I don't think we want to introduce any data management responsibilities into vue-router.

PS: if vuex and its concepts is to alien or is is too much for your specific app's usecase, there's other soultions as well, including a simple shared, global object as explained here. That can be enough in many situations.

Hmm. I'm not sure why routes are treated _that_ differently than child components.

Child routes are almost like a chain of v-else-if in order to determine which component will be shown based on a string. You can pass data into children components. Why not pass data into children routes? Data still flows downwards.

I understand that Vuex is the solution if the application has a lot of shared state. But I'm not sure that implementing whole application in Vuex style because of this use-case is justified, either.

Angular solves this with services which can be injected into multiple components and thus share data, even they are not on the same route. Is there really _no_ way to share data between two unrelated components without going full Vuex? Would $emit work at least? If I $emit data from source route, and subscribe in the destination route on its component's creation, is the order of execution guaranteeed and will it "catch" sent data?

Hmm. I'm not sure why routes are treated that differently than child components.

They are not. You can pass props to child router-views, so you can pass data down from parent route components to child route components.

However having the ability of passing data from any location in the component tree to some (possibly very distant) route component (which I understand is what you're asking for) is not following the data-down approach - it's what this approach wants to get rid of.

You obviously have shared state, so don't send it from one component to the other, keep it in one place.

Is there really no way to share data between two unrelated components without going full Vuex?

Have a look at my previous post, maybe my quick edit of the last paragraph wasn't quick enough and you missed it, already reading the previous, unedited version. Also, feel free to have a look at our awesome-vue repo - vuex is not the only state management solution, there are other ones out there, and not all are as "verbose" as vuex.

Hi guys,
I'm new to vue js. i want to know about how to pass the service router-link <router-link :to></router-link> <router-link v-bind:to="'/newsDisplay/' + i.id"></router-link>. i have the news list. when i click the news list item calling newsDisplay page through list ID. i want to call service in router-link. ``

Please use forum.vuejs.org for questions.

Was this page helpful?
0 / 5 - 0 ratings