Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a nice way to pass props to the parent component with Vue router?

I have a form with different steps that all share the same header structure.

The only difference in the header within the different steps is wording in that header which changes along the steps.

I am searching for a way to do this:

In my vue router :

      path: '/form',
      name: 'Form',
      component: Form,
      children: [
        {
          path: 'step1',
          component: FormStep1,
          propsForParent: {
            title: "myTitle In Header In Form Component"
          },
        },
        {
          path: 'step2',
          component: FormStep2,
          propsForParent: {
            title: "myTitle is different In Header In Form Component"
          },
        }
      ]

Therefore when the route is form/step1 I would like my form component to receive the title props set in my children configuration as described above and so on.

I would like to avoid managing that in my parent component and also avoid my child to communicate this information with an event for instance to my parent component or using vuex. I am searching for something nice directly in vue router.

Any idea?

like image 302
Clement Levesque Avatar asked Aug 11 '18 06:08

Clement Levesque


1 Answers

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.

like image 156
BroiSatse Avatar answered Oct 14 '22 07:10

BroiSatse