如何在Algolia Vue InstantSearch的searchStore中实现结果堆叠?
实现自定义组件的堆叠搜索结果功能
首先得明确:stack是<ais-results>组件的专属属性,没办法直接给searchStore设置这个属性。不过我们可以手动复刻它的堆叠逻辑——核心就是维护一个累积所有已加载页结果的数组,而不是每次页码变化都替换成新页的结果。
下面是具体的实现步骤,直接修改你的自定义组件即可:
1. 新增数据属性维护堆叠结果
在组件的data里添加两个变量:
stackedResults:用来存储所有已加载的搜索结果(堆叠后的集合)lastLoadedPage:记录最后加载过的页码,避免重复加载同一页的内容
2. 监听搜索结果变化,实现堆叠逻辑
通过watch监听searchStore.results的变化,根据当前页码决定是初始化结果还是追加新页结果:
- 当页码重置为0(比如用户输入新的搜索关键词),直接替换
stackedResults为新的第一页结果 - 当页码大于上次加载的页码(调用
loadMore后),把新页的结果追加到stackedResults里
3. 修改计算属性基于堆叠结果
把原来返回this.searchStore.results的results计算属性,改成返回this.stackedResults,这样你的rows分块逻辑就会基于所有堆叠后的结果来处理。
修改后的完整组件代码
import { Component } from "vue-instantsearch"; export default { components: { "v-image": VImage }, mixins: [Component], data() { return { stackedResults: [], lastLoadedPage: 0 }; }, watch: { 'searchStore.results': { immediate: true, handler(newResults) { // 搜索关键词变化时,页码会重置为0,此时重置堆叠结果 if (this.searchStore.page === 0) { this.stackedResults = newResults; this.lastLoadedPage = 0; return; } // 加载新页时,追加结果到堆叠数组 if (this.searchStore.page > this.lastLoadedPage) { this.stackedResults = [...this.stackedResults, ...newResults]; this.lastLoadedPage = this.searchStore.page; } } } }, methods: { loadMore() { this.searchStore.page++; } }, computed: { results() { return this.stackedResults; }, rows() { var arr = this.results; var len = 3; var chunks = [], i = 0, n = arr.length; while (i < n) { chunks.push(arr.slice(i, (i += len))); } return chunks; } } };
原理说明
<ais-results>的:stack="true"本质就是内部做了类似的逻辑:维护一个私有数组,每次页码增加时把新页的结果追加进去,而不是替换。我们自定义组件时,只需要手动实现这个累积结果的逻辑就行,完全不需要依赖组件的内置属性。
内容的提问来源于stack exchange,提问作者Djave
相关产品推荐
相关产品推荐

