【问题标题】:Dynamically rendering child components in Vue.js v2在 Vue.js v2 中动态渲染子组件
【发布时间】:2018-06-23 13:54:02
【问题描述】:

我正在用 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 可读性较差,对开发人员友好。

有没有更好的办法?

【问题讨论】:

  • 使用道具而不是插槽是正确的方法。插槽不是子级。

标签: javascript vue.js vuejs2 vue-component


【解决方案1】:

我想你想为此使用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>

【讨论】:

    【解决方案2】:

    使用 scoped-slots 能解决您的问题吗?然后,您可以提供自定义渲染子组件。 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'
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-21
      • 2017-08-17
      • 2021-12-28
      • 1970-01-01
      • 2022-01-25
      • 2023-04-11
      • 2018-01-24
      • 1970-01-01
      相关资源
      最近更新 更多