关于Algolia InstantSearch Vue ais-dynamic-widgets组件的动态展示疑问
我们在用Algolia InstantSearch Vue组件搭建搜索功能时,希望利用Algolia的动态Facet特性——根据当前搜索结果自动展示匹配的筛选条件(比如搜索手机时显示memory,搜索电视时显示size),并且已经在Algolia控制台配置好了Facet及展示规则。
尝试用ais-dynamic-widgets组件实现,但发现官方示例里仍需手动罗列所有可能的Facet组件:
<ais-dynamic-widgets> <ais-refinement-list attribute="brand" /> <ais-panel> <ais-menu attribute="categories" /> </ais-panel> <ais-hierarchical-menu :attributes="['categories']" /> </ais-dynamic-widgets>
通过Vue Inspector能看到ais-dynamic-widgets已经识别出符合条件的Facet,存放在内部的data.state.attributesToRender里,但直接在模板里引用这个值行不通,同时也不确定循环渲染是否能自动只显示适用的Facet。
问题1:如何获取attributesToRender数据?
ais-dynamic-widgets的内部状态无法直接在外部模板访问,需要用官方提供的**组合式函数useDynamicWidgets**来获取这个列表(Vue 3适用):
- 首先导入该函数
- 在组件的
setup中调用函数,解构出attributesToRender - 之后就可以在模板中直接使用这个变量
示例代码:
<script setup> import { useDynamicWidgets } from 'vue-instantsearch/vue3/es'; // 获取动态渲染的Facet属性列表 const { attributesToRender } = useDynamicWidgets(); </script> <template> <ais-dynamic-widgets> <ais-refinement-list v-for="attr in attributesToRender" :key="attr" :attribute="attr" /> </ais-dynamic-widgets> </template>
如果是Vue 2项目,可以通过inject获取组件内部提供的状态,或者使用组件的scoped slot来传递数据。
问题2:循环渲染是否会自动只显示适用的Facet?
是的。attributesToRender本身就是Algolia根据当前搜索结果、结合你在控制台配置的动态展示规则筛选出来的Facet属性集合——只有当前结果集对应的、符合展示条件的Facet才会出现在这个列表里,所以循环它渲染的组件只会显示适用的筛选条件,不需要额外做判断。
进阶:根据Facet类型使用不同组件
如果需要给不同的Facet属性匹配不同类型的组件(比如categories用ais-menu,其他用ais-refinement-list),可以通过transformItems配置来扩展属性信息:
<script setup> import { useDynamicWidgets } from 'vue-instantsearch/vue3/es'; import { AisMenu, AisRefinementList } from 'vue-instantsearch/vue3/es'; const { attributesToRender } = useDynamicWidgets({ transformItems(items) { return items.map(item => ({ ...item, // 根据属性名指定对应的组件 component: item.attribute === 'categories' ? AisMenu : AisRefinementList })); } }); </script> <template> <ais-dynamic-widgets> <component v-for="item in attributesToRender" :key="item.attribute" :is="item.component" :attribute="item.attribute" /> </ais-dynamic-widgets> </template>
内容的提问来源于stack exchange,提问作者Adam Hopkinson

