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

时间:2017-03-24 06:11:58

标签: javascript vue.js vuejs2 vue-component

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

声明,注册并使用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:无法读取属性&#39; name&#39;未定义的

     

TypeError:无法读取属性&#39; setAttribute&#39;未定义的

显然我做错了什么

4 个答案:

答案 0 :(得分:15)

总结:

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

答案 1 :(得分:14)

您可以使用特殊属性is来执行此类操作。可以找到动态组件及其用法的示例here

  

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

您的代码如下所示:

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

答案 2 :(得分:1)

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

<script>
$(document).ready(function(){

$("svg").click(function(){
  var id = $(this).attr('id');
  decision = window.confirm("Are you sure you want to delete this class?");
  if (decision === true) {
    var url = '/classes/' + id + '/delete';
    jQuery.get(url, function(){
      console.log("It worked.");
      $(this).closest('tr').hide();
    });
  }
 });

});
</script>

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

答案 3 :(得分:0)

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

: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元素之间交替。