在Vue.js v2中动态呈现子组件

时间:2018-01-14 21:39:35

标签: javascript vue.js vuejs2 vue-component

我在VueJS中构建了一个分面搜索系统。一般的想法很简单:

FilterGroup组件包含整体过滤器逻辑。该组件接受各种子组件,例如AttributeXYZFilter。这些子组件负责提供FilterGroup将用于过滤项目集合的条件。

此系统的示例用法如下所示:

<template>
  <FilterGroup :items="items">
    <ABCFilter/>
    <XYZFilter/>
    <AnotherFilter/>
  </FilterGroup>
</template>

我的问题如下:

过滤器组件应由FilterGroup以特定布局呈现。此外,FilterGroup应该使用props为过滤器组件提供一些额外的数据。

为了避免不必要的耦合,FilterGroup不应该知道将呈现哪些过滤器。每个过滤器都遵循通用规范/接口(使用mixins实现)。每个过滤器都有自己的UI模板。

如何实施?

我尝试使用插槽,但我无法弄清楚如何自定义渲染子组件。如果没有使用广告位,则this.$children为空,因此我不知道要呈现哪些过滤器。

我可以像这样提供过滤器:

<template>
  <FilterGroup :items="items" :filters="['ABCFilter', 'XYZFilter']/>
</template>

然后FilterGroup可以动态导入和呈现过滤器组件。甚至可以传递额外的数据。但是,我认为生成的API不太易读且对开发人员友好。

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

我认为您希望使用Dynamic Components。这允许您基于数据动态呈现(子)组件。在您的示例中为过滤器。

:is="ComponentName"定义应呈现的组件。使用props传递数据:

<template>
    <div class="app-body row">
        <template v-for="(child, index) in children">
            <component :is="child.viewName" :key="child.name" :data="child.data"></component>
        </template>
    </div>
</template>

答案 1 :(得分:0)

使用范围插槽可以解决您的问题吗?然后,您可以提供自定义渲染子组件。 JSFiddle

Vue.component('filter-group', {
  template: `
  <div class="filter-group">
    <slot :items="items">
    </slot>
  </div>
  `,
  data: function() {
    return {
      items: [1, 2, 3, 4, 5]
    }
  }
})

Vue.component('filter-a', {
  template: `
  <div class="filter-a">
    filter a: {{ items }}
  </div>
  `,
  props: ['items']
})

Vue.component('filter-b', {
  template: `
  <div class="filter-b">
    filter b: {{ items }}
  </div>
  `,
  props: ['items']
})

new Vue({
  el: '#app'
})