有没有一种很好的方法可以使用 Vue 路由器将 props 传递给父组件?

Cle*_*que 7 javascript vue.js vue-router

我有一个具有不同步骤的表单,它们都共享相同的标题结构。

不同步骤中标题的唯一区别是该标题中的措辞随着步骤而变化。

我正在寻找一种方法来做到这一点:

在我的 vue 路由器中:

      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"
          },
        }
      ]
Run Code Online (Sandbox Code Playgroud)

因此,当路由是 form/step1 时,我希望我的表单组件接收在我的子配置中设置的标题道具,如上所述等等。

我想避免在我的父组件中管理它,也避免我的孩子将此信息与事件传达给我的父组件或使用 vuex。我正在 vue 路由器中直接搜索一些不错的东西。

任何的想法?

Bro*_*tse 8

使用路由元数据:

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"
    },
  }
]
Run Code Online (Sandbox Code Playgroud)

然后在你的父组件中:

computed: {
  title () { this.$route.meta.title }
}
Run Code Online (Sandbox Code Playgroud)

如果您希望将 title 作为 prop 传递给父组件,请使用:

routes: [{
  path: '/form',
  name: 'Form',
  component: Form,
  props (route) => {
    return {
      title: route.meta.title
    }
  }
  children: [ ...
Run Code Online (Sandbox Code Playgroud)

您还可以使头衔可继承。为此,您需要使用更复杂的检查:

const matched = route.matched.slice().reverse().find(route => route.meta.title)
matched.meta.title
Run Code Online (Sandbox Code Playgroud)

注意:这slice()似乎什么也没做,但它正在创建匹配数组的副本,因此我们不会修改原始数组 - 删除slice()会毁掉你的调试一天。


Squ*_*gs. 3

你已经快到了,只需将收到的 prop 值从子级发送到父级即可。

      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;
    }
  }
Run Code Online (Sandbox Code Playgroud)

为了使事情更清晰,请考虑在路由器内创建另一层子级,这样您就不必对每个子级进行发射。这是我现在正在查看的一个项目中的一些代码,它做了一些非常相似的事情,请注意我正在传递的步骤道具。

//在我的timelineBase组件中,我监听onChildInit,设置一个方法来从子组件中获取值,然后在布局中使用它来告诉pageStepper我所在的部分。

<router-view v-on:childinit="onChildInit" :key="componentKey"></router-view>
<pageStepper :step="pageStepper"></pageStepper>
Run Code Online (Sandbox Code Playgroud)

//代码有这些道具。道具:['模式','步骤','componentKey'],

这是我的路线。

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 }
                  },
              ]
          },


        ]
      }
    ]
});
Run Code Online (Sandbox Code Playgroud)