我在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不太易读且对开发人员友好。
有更好的方法吗?
答案 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'
})