Javascript 是否可以将组件作为道具传递并在 Vue 的子组件中使用它?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/42992579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:35:06  来源:igfitidea点击:

Is it possible to pass a component as props and use it in a child Component in Vue?

javascriptvue.jsvuejs2vue-component

提问by Victor Ferreira

In a Vue 2.0 app, let's say we have components A, B and C.

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

A declares, registers and uses B

A 声明、注册和使用 B

Is it possible to pass C from A to B?

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

Something like this:

像这样的东西:

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

And use C in B somehow.

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

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

The motivation: I want to create a generic component Bthat is used in Abut receives from Aits child C. Actually Awill use Bseveral times passing different 'C's to it.

动机:我想创建一个通用组件B,用于A但从A其 child接收C。实际上AB多次使用不同的'C'。

If this approach is not correct, what is the proper way of doing it in Vue?

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

Answering @Saurabh

回答@Saurabh

Instead of passing as props, I tried the suggestion inside B.

我没有作为道具传递,而是尝试了 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: []
 }
}

Basically I'm trying to render Equipment, but the dynamic way

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

I get 3 errors in console and a blank page

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

[Vue warn]: Error when rendering component at /home/victor/projetos/tokaai/public/src/components/EquipmentFormItem.vue:

Uncaught TypeError: Cannot read property 'name' of undefined

TypeError: Cannot read property 'setAttribute' of undefined

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

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

类型错误:无法读取未定义的属性“setAttribute”

Apparently I'm doing something wrong

显然我做错了什么

采纳答案by Saurabh

You can use special attribute isfor doing this kind of thing. Example of dynamic component and it's usage can be found here.

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

You can use the same mount point and dynamically switch between multiple components using the reserved element and dynamically bind to its is attribute:

您可以使用相同的挂载点并使用保留元素在多个组件之间动态切换并动态绑定到其 is 属性:

Your code will look like following:

您的代码将如下所示:

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

回答by Jonatas Walker

Summing up:

加起来:

<!-- 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>

回答by NiBi

Here's solution to forward custom component through props of another component

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

:isis special attribute and it will be used to replace your actual component and it will be ignored if you try to use it as a prop in your component. Luckily you can use something else like eland then forward this to componentlike so:

: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>

Any valid element you use in elattribute will be used as a child component. It can be html or reference to your custom component or divby default as specified in component declaration.

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

Passing custom component to prop is little bit tricky. One would assume you declare in a componentsproperty of parent component and then use it for elattribute but this doesn't work. Instead you need to have your dynamic component in dataor computedproperty so you can use it in a template as a prop. Also note AnotherComponentdoesn't need to be declared in componentsproperty.

将自定义组件传递给 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>

Using computed property for your dynamic component allows you to switch between components easily:

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

<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>

Increase this.countto alternate between AnotherComponentand simple articlehtml element.

增加和简单的html 元素this.count之间的交替。AnotherComponentarticle