【问题标题】:Is it possible to pass a component as props and use it in a child Component in Vue?是否可以将组件作为道具传递并在 Vue 的子组件中使用它?
【发布时间】:2019-03-04 12:08:33
【问题描述】:

在 Vue 2.0 应用程序中,假设我们有组件 A、B 和 C。

A 声明、注册和使用 B

是否可以将 C 从 A 传递到 B?

类似这样的:

<template>
  <div class="A">
    <B :child_component="C" />
  </div>
</template>

并以某种方式在 B 中使用 C。

<template>
  <div class="B">
    <C>Something else</C>
  </div>
</template>

动机:我想创建一个通用组件B,它在A 中使用,但从A 接收它的子组件C。实际上A 会使用B 多次传递不同的'C'。

如果这种方法不正确,在 Vue 中正确的做法是什么?

回答@Saurabh

我尝试了 B 内部的建议,而不是作为道具传递。

<!-- this is where I Call the dynamic component in B -->

<component :is="child_component"></component>

//this is what I did in B js
components: {
 equip: Equipment
}, 
data () {
 return {
   child_component: 'equip',
   _list: []
 }
}

基本上我是在尝试渲染设备,但是动态的方式

我在控制台中遇到 3 个错误和一个空白页

[Vue 警告]:在 /home/victor/projetos/tokaai/public/src/components/EquipmentFormItem.vue 处渲染组件时出错:

未捕获的类型错误:无法读取未定义的属性“名称”

TypeError: 无法读取未定义的属性“setAttribute”

显然我做错了什么

【问题讨论】:

  • 您确定这些错误仅来自这些代码吗?您在哪里使用setAttribute name 属性?
  • 必须是某个内部进程。我没有在这个应用程序中这样做

标签: javascript vue.js vuejs2 vue-component


【解决方案1】:

总结:

<!-- Component A -->
<template>
  <div class="A">
    <B>
      <component :is="child_component"></component>
    </B>
  </div>
</template>

<script>
import B from './B.vue';
import Equipment from './Equipment.vue';

export default {
  name: 'A',
  components: { B, Equipment },
  data() {
    return { child_component: 'equipment' };
  }
};
</script>

<!-- Component B -->
<template>
  <div class="B">
    <h1>Some content</h1>
    <slot></slot> <!-- Component C will appear here -->
  </div>
</template>

【讨论】:

  • 这很好用,谢谢。我对此进行了跟进。现在想象组件 C 发出一个事件,我想在组件 B 中对它采取行动。我尝试在 上使用 v-on 来监听它,但这不起作用。我在这里有什么选择?
  • 得到了答案!我只会在祖父母中监听事件,即 而不是在注入它的插槽上监听它。
  • 我们必须导入我们有``标签的所有子组件。如果我们只需要来自父级的特定子组件,它会不会让它变慢。有什么解决方法可以让我们在父组件中导入组件并将其传递给子组件?
【解决方案2】:

你可以使用特殊属性is 来做这种事情。动态组件的示例及其用法可以在here 找到。

可以使用同一个挂载点,使用reserved元素在多个组件之间动态切换,动态绑定到它的is属性:

您的代码将如下所示:

<template>
  <div class="B">
    <component :is="child_component"> Something else</component>
  </div>
</template>

【讨论】:

  • 这里不工作,但我不知道到底发生了什么。我会用更多信息更新我的问题
  • 像魅力一样工作!谢谢!我想知道是否可以使用传递的组件而不是Object 类型设置道具的自定义类型?比如:passedComponent: { type: Component, required: true },
  • 另外,通过prop接收这个组件的组件中,是否可以得到传递的组件的名称?
【解决方案3】:

这里是通过另一个组件的props转发自定义组件的解决方案

:is 是特殊属性,它将用于替换您的实际组件,如果您尝试将其用作组件中的道具,它将被忽略。幸运的是,您可以使用 el 之类的其他内容,然后将其转发给 component,如下所示:

<template>
  <div>
    <component :is="el">
      <slot />
    </component>
  </div>
</template>
<script>
  export default {
    name: 'RenderDynamicChild',
    props: {
        el: {
            type: [String, Object],
            default: 'div',
        },
    },
  }
</script>

您在el 属性中使用的任何有效元素都将用作子组件。它可以是 html 或引用您的自定义组件或 div 默认情况下在组件声明中指定。

将自定义组件传递给 prop 有点棘手。假设您在父组件的components 属性中声明,然后将其用于el 属性,但这不起作用。相反,您需要将动态组件放在 datacomputed 属性中,以便您可以在模板中将其用作道具。另请注意 AnotherComponent 不需要在 components 属性中声明。

<template>
  <RenderDynamicChild :el="DynamicComponent">
    Hello Vue!
  </RenderDynamicChild>
</template>

<script>
import RenderDynamicChild from './DynamicChild';
import AnotherComponent from './AnotherComponent';

export default {
  name: "ParentComponent",
  components: { DynamicChild },
  data() {
    return {
      DynamicComponent: AnotherComponent,
    };
  },
};
</script>

为你的动态组件使用计算属性可以让你在组件之间轻松切换:

<script>
import DynamicChild from './DynamicChild';
import AnotherComponent from './AnotherComponent';

export default {
  name: "ParentComponent",
  components: { DynamicChild },
  data() { return { count: 0 } },
  computed: {
    DynamicComponent() {
      return this.count % 2 > 1 ? AnotherComponent : 'article';
    },
  },
};
</script>

增加this.count 以在AnotherComponent 和简单的article html 元素之间交替。

【讨论】:

    【解决方案4】:

    如果您想在功能组件中使用其他组件,您可以执行以下操作:

    <script>
      import Vue from 'vue'
      import childComponent from './childComponent'
      Vue.component('child-component')
      export default {}
    </script>
    
    
    <template functional>
      <div>
        <child-component/>
      </div>
    </template>
    

    参考: https://github.com/vuejs/vue/issues/7492#issue-290242300

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-01
      • 2022-01-25
      • 2020-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      相关资源
      最近更新 更多