[英]Is it possible to pass a component as props and use it in a child Component in Vue?
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 B
that is used in A
but receives from A
its child C
.动机:我想创建一个在
A
中使用但从A
接收其子C
的通用组件B
。 Actually A
will use B
several times passing different 'C's to it.实际上
A
会多次使用B
传递不同的 '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:
[Vue 警告]:在 /home/victor/projetos/tokaai/public/src/components/EquipmentFormItem.vue 处渲染组件时出错:
Uncaught TypeError: Cannot read property 'name' of undefined
未捕获的类型错误:无法读取未定义的属性“名称”
TypeError: Cannot read property 'setAttribute' of undefined
TypeError:无法读取未定义的属性“setAttribute”
Apparently I'm doing something wrong显然我做错了什么
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>
You can use special attribute is
for doing this kind of thing.你可以使用特殊
is
来做这种事情。 Example of dynamic component and its usage can be found here .可以在此处找到动态组件及其用法的示例。
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>
Here's solution to forward custom component through props of another component这是通过另一个组件的道具转发自定义组件的解决方案
:is
is 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. :is
是特殊属性,它将用于替换您的实际组件,如果您尝试将其用作组件中的道具,它将被忽略。 Luckily you can use something else like el
and then forward this to component
like so:幸运的是,您可以使用
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 el
attribute will be used as a child component.您在
el
属性中使用的任何有效元素都将用作子组件。 It can be html or reference to your custom component or div
by default as specified in component declaration.默认情况下,它可以是 html 或对您的自定义组件或
div
的引用,如组件声明中指定的那样。
Passing custom component to prop is little bit tricky.将自定义组件传递给 prop 有点棘手。 One would assume you declare in a
components
property of parent component and then use it for el
attribute but this doesn't work.有人会假设您在父组件的
components
属性中声明,然后将其用于el
属性,但这不起作用。 Instead you need to have your dynamic component in data
or computed
property so you can use it in a template as a prop.相反,您需要将动态组件放在
data
或computed
属性中,以便可以在模板中将其用作道具。 Also note AnotherComponent
doesn't need to be declared in components
property.另请注意
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.count
to alternate between AnotherComponent
and simple article
html element.增加
this.count
以在AnotherComponent
和简单的article
html 元素之间交替。
If you would like to use another component within your functional component you can do the following:如果您想在功能组件中使用另一个组件,您可以执行以下操作:
<script>
import Vue from 'vue'
import childComponent from './childComponent'
Vue.component('child-component')
export default {}
</script>
<template functional>
<div>
<child-component/>
</div>
</template>
Reference: https://github.com/vuejs/vue/issues/7492#issue-290242300参考: https ://github.com/vuejs/vue/issues/7492#issue-290242300
Maybe it's too late to answer this question.也许现在回答这个问题为时已晚。 But I think it could help others with this same issue.
但我认为它可以帮助其他人解决同样的问题。
I've been looking for a way to pass components throw others in vue, but it looks that VUE3 have a approach for that using named slots:我一直在寻找一种在 vue 中传递组件的方法,但看起来 VUE3 有一种使用命名插槽的方法:
Here it's the documentation about that: https://v3.vuejs.org/guide/component-slots.html#named-slots这是关于它的文档: https ://v3.vuejs.org/guide/component-slots.html#named-slots
Basically you can have:基本上你可以拥有:
<template>
<div class="A">
<slot name="ComponentC"></slot> <!-- Here will be rendered your ComponentC -->
</div>
<div class="A">
<slot name="ComponentD"></slot> <!-- Here will be rendered your ComponentD -->
</div>
<div class="A">
<slot></slot> <!-- This is going to be children components -->
</div>
</template>
And from your B
component从你的
B
组件
<template>
<div class="B">
<A>
<template v-slot:ComponentC>
<h1>Title of ComponentC </h1>
</template>
<template v-slot:ComponentD>
<h1>Title of ComponentD </h1>
</template>
<template v-slot:default>
<h1>Title of child component </h1>
</template>
</A>
</div>
</template>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.