Is there a nice way to pass props to the parent component with Vue router?
Use route meta data:
path: '/form',
name: 'Form',
component: Form,
children: [
{
path: 'step1',
component: FormStep1,
meta: {
title: "myTitle In Header In Form Component"
},
},
{
path: 'step2',
component: FormStep2,
meta: {
title: "myTitle is different In Header In Form Component"
},
}
]
And then in your parent component:
computed: {
title () { this.$route.meta.title }
}
If you prefer title be passed as a prop to you parent component, use:
routes: [{
path: '/form',
name: 'Form',
component: Form,
props (route) => {
return {
title: route.meta.title
}
}
children: [ ...
You could also make title inheritable. For that you need to use a bit more complicated check:
const matched = route.matched.slice().reverse().find(route => route.meta.title)
matched.meta.title
Note: that slice()
seems to do nothing, but it is creating a copy of matched array so we don't modify the original array - removing slice()
will ruin your day with debugging.
You are nearly there, just emit from child to the parent with the value of the prop received.
path: '/form',
name: 'Form',
component: Form,
children: [
{
path: 'step1',
component: FormStep1,
props: {
title: "myTitle In Header In Form Component"
},
},
{
path: 'step2',
component: FormStep2,
props: {
title: "myTitle is different In Header In Form Component"
},
}
]
//Inside FormStep2 and FormStep1
created() {
this.$emit('childinit', this.title);
},
//inside Form
methods: {
onChildInit( value ){
this.title = value;
}
}
To make things cleaner, consider creating another layer of children inside your router, so you don't have to emit on every child. Here's some code out of a project I'm looking at right now that does something very similar notice the step prop which I'm passing about.
//inside my timelineBase component I listen for onChildInit, set a method to grab value from the child, then use that in the layout to tell pageStepper what section I'm in.
<router-view v-on:childinit="onChildInit" :key="componentKey"></router-view>
<pageStepper :step="pageStepper"></pageStepper>
//code has these props. props: ['mode','step','componentKey'],
This is my routes.
const router = new VueRouter({
routes: [
{
path: '/',
component: Layout,
children: [
{
path: '',
component: homepage,
props: { cssClass: '' },
},
{
name: 'addTimeline',
path: 'timeline',
props: { mode:'add', step: 1, componentKey: 0 },
component: timelineBase,
children:
[
{
path: 'add',
component: timeline,
props: { mode:'add', step: 1, componentKey: 1},
},
{
name: 'updateTimeline',
path: ':id/update',
component: timeline,
props: { mode:'update', step: 1, componentKey: 2 }
},
{
name: 'addEvent',
path: ':id/event/add',
component: addevent,
props: { mode:'add', step: 2, componentKey: 3 }
},
{
name: 'editEvent',
path: ':id/event/edit/:event_id',
component: editevent,
props: { mode:'update', step: 2, componentKey: 4 }
},
{
name: 'previewTimeline',
path: ':id/preview',
component: preview,
props: { step: 3, componentKey: 5 }
},
]
},
]
}
]
});