有没有一种很好的方法可以使用 Vue 路由器将道具传递给 parent 组件?
Is there a nice way to pass props to the parent component with Vue router?
我有一个包含不同步骤的表单,这些步骤都共享相同的 header 结构。
不同步骤中 header 的唯一区别是 header 的措辞随着步骤的变化而变化。
我正在寻找一种方法来做到这一点:
在我的 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"
},
}
]
因此,当路由是 form/step1 时,我希望我的表单组件接收在我的 children 配置中设置的标题道具,如上所述等等。
我想避免在我的 parent 组件中管理它,也避免我的 child 将此信息与事件通信,例如我的 parent 组件或使用 vuex。我直接在 vue router 中搜索一些不错的东西。
有什么想法吗?
你就快到了,只需从 child 发射到 parent 与收到的 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;
}
}
为了让事情更清晰,考虑在你的路由器中创建另一层 children,这样你就不必在每个 child 上发射。这是我正在查看的项目中的一些代码,它做了一些非常相似的事情,请注意我正在传递的 step 道具。
//在我的 timelineBase 组件中,我监听 onChildInit,设置一个方法来从 child 中获取值,然后在布局中使用它来告诉 pageStepper 我在哪个部分。
<router-view v-on:childinit="onChildInit" :key="componentKey"></router-view>
<pageStepper :step="pageStepper"></pageStepper>
//代码有这些道具。
道具:['mode','step','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 }
},
]
},
]
}
]
});
您还可以Vuex
或localStorage
来管理道具。顺便说一句,Vuex
中的值会在刷新后被清除。
可能会有一些改进,以更优雅的方式实现它。
作为斯奎格斯。提到过,我们可以在每个子组件中发出 childinit
,每次都在子组件中编写发出的东西会很乏味。
不过我们可以使用 mixin 来解决这个问题。我们编写了一个 mixin 来发出 childinit
及其 props,并在每个子组件中导入和使用这个 mixin。
// mixin
export default {
props: {
title: {
type: String,
default: '',
},
},
created() {
this.$emit('childinit', this.title)
},
}
// parent
<template>
<div class="wrapper">
<router-view @childinit="childInit"/>
</div>
</template>
<script>
export default {
data() {
return {
title: '',
}
},
methods: {
childInit(title) {
this.title = title
},
},
}
</script>
// child
<script>
import TitleMixin from './mixins'
export default {
mixins: [TitleMixin],
}
</script>
使用路由元数据:
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"
},
}
]
然后在您的 parent 组件中:
computed: {
title () { this.$route.meta.title }
}
如果您希望将标题作为道具传递给您 parent 组件,请使用:
routes: [{
path: '/form',
name: 'Form',
component: Form,
props (route) => {
return {
title: route.meta.title
}
}
children: [ ...
您还可以将头衔设为可继承。为此,您需要使用更复杂的检查:
const matched = route.matched.slice().reverse().find(route => route.meta.title)
matched.meta.title
注意:slice()
似乎什么都不做,但它正在创建匹配数组的副本,因此我们不会修改原始数组 - 删除 slice()
会毁掉你调试的一天。
我有一个包含不同步骤的表单,这些步骤都共享相同的 header 结构。
不同步骤中 header 的唯一区别是 header 的措辞随着步骤的变化而变化。
我正在寻找一种方法来做到这一点:
在我的 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"
},
}
]
因此,当路由是 form/step1 时,我希望我的表单组件接收在我的 children 配置中设置的标题道具,如上所述等等。
我想避免在我的 parent 组件中管理它,也避免我的 child 将此信息与事件通信,例如我的 parent 组件或使用 vuex。我直接在 vue router 中搜索一些不错的东西。
有什么想法吗?
你就快到了,只需从 child 发射到 parent 与收到的 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;
}
}
为了让事情更清晰,考虑在你的路由器中创建另一层 children,这样你就不必在每个 child 上发射。这是我正在查看的项目中的一些代码,它做了一些非常相似的事情,请注意我正在传递的 step 道具。
//在我的 timelineBase 组件中,我监听 onChildInit,设置一个方法来从 child 中获取值,然后在布局中使用它来告诉 pageStepper 我在哪个部分。
<router-view v-on:childinit="onChildInit" :key="componentKey"></router-view>
<pageStepper :step="pageStepper"></pageStepper>
//代码有这些道具。 道具:['mode','step','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 }
},
]
},
]
}
]
});
您还可以Vuex
或localStorage
来管理道具。顺便说一句,Vuex
中的值会在刷新后被清除。
可能会有一些改进,以更优雅的方式实现它。
作为斯奎格斯。提到过,我们可以在每个子组件中发出 childinit
,每次都在子组件中编写发出的东西会很乏味。
不过我们可以使用 mixin 来解决这个问题。我们编写了一个 mixin 来发出 childinit
及其 props,并在每个子组件中导入和使用这个 mixin。
// mixin
export default {
props: {
title: {
type: String,
default: '',
},
},
created() {
this.$emit('childinit', this.title)
},
}
// parent
<template>
<div class="wrapper">
<router-view @childinit="childInit"/>
</div>
</template>
<script>
export default {
data() {
return {
title: '',
}
},
methods: {
childInit(title) {
this.title = title
},
},
}
</script>
// child
<script>
import TitleMixin from './mixins'
export default {
mixins: [TitleMixin],
}
</script>
使用路由元数据:
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"
},
}
]
然后在您的 parent 组件中:
computed: {
title () { this.$route.meta.title }
}
如果您希望将标题作为道具传递给您 parent 组件,请使用:
routes: [{
path: '/form',
name: 'Form',
component: Form,
props (route) => {
return {
title: route.meta.title
}
}
children: [ ...
您还可以将头衔设为可继承。为此,您需要使用更复杂的检查:
const matched = route.matched.slice().reverse().find(route => route.meta.title)
matched.meta.title
注意:slice()
似乎什么都不做,但它正在创建匹配数组的副本,因此我们不会修改原始数组 - 删除 slice()
会毁掉你调试的一天。