发布于 2026-01-06 2 阅读
0

在 Vue 中将所有道具传递给孩子们

在 Vue 中将所有道具传递给孩子们

这篇文章也发布在我的博客上。

在构思一些新的 Vue 组件时,我希望有一个方法,让一个包装组件能够获取子视图所需的所有数据,并将这些数据传递给(大约 5 层)子组件,直至最底层。

所以我做了一些实验,这里提供一种将所有组件属性传递给子组件的方法。链接到 CodePen

Vue 实际上让这一切变得非常简单。所有组件属性都存在于$props对象中(this.$props除非你正在使用模板),我们可以使用 Vue 指令,而v-bind无需指定具体的属性名称,即可将整个属性对象绑定到子组件。

例子

假设我们有一个包装组件,它将渲染一个子comp1组件,并将两者作为 props 传递给propForComp1propForComp2

以下是Comp1.vue

<template>
  <div class="comp1">
    <span>{{ propForComp1 }}</span>
    <comp2 v-bind="$props" />
  </div>
</template>

<script>
  export default {
    components: Comp2,
    props: [
      'propForComp1',
      'propForComp2'
    ],
  }
</script>
Enter fullscreen mode Exit fullscreen mode

请注意,comp1它只使用` propForComp1<class>`,并不真正关心 `<class> propForComp2`。但由于它需要包含在传递给 `<class>` 的 props 中comp2propForComp2因此仍然需要在props对象内部声明。否则,`<class>`$props将不会包含它。

你可以对多层组件进行这种操作,但请记住,任何子组件所需的 props必须在所有父组件中声明。因此,如果你有 5 层组件,则必须在` <component>`、`<component>` 、 `<component> `、` <component>` 和`<component>`propForComp5中声明为 prop 。你可以使用 Mixin 来简化这个过程,这也是我在CodePen 示例中采用的方法prop1prop2prop3prop4prop5

更新:其实最后一步不用做!就像 Vue 放弃的那样$props$attrs对象包含了组件声明为 props 的所有传递属性。这意味着,v-bind="$attrs"即使组件本身没有指定这些属性,我们也可以简单地使用它来传递子组件需要的属性。

前面的例子会变成:

<template>
  <div class="comp1">
    <span>{{ propForComp1 }}</span>
    <comp2 v-bind="$props" v-bind="$attrs" />
  </div>
</template>

<script>
  export default {
    components: Comp2,
    props: [
      'propForComp1'
    ],
  }
</script>
Enter fullscreen mode Exit fullscreen mode

通过比较差异来查看更改:

<template>
  <div class="comp1">
    <span>{{ propForComp1 }}</span>
-   <comp2 v-bind="$props" />
+   <comp2 v-bind="$props" v-bind="$attrs" />
  </div>
</template>

<script>
  export default {
    components: Comp2,
    props: [
      'propForComp1',
-     'propForComp2'
    ],
  }
</script>
Enter fullscreen mode Exit fullscreen mode

感谢@morficus指出这一点!

文章来源:https://dev.to/jwkicklighter/pass-all-props-to-children-in-vue-9on