Algolia vue Instantsearch 动态设置搜索查询

Posted

技术标签:

【中文标题】Algolia vue Instantsearch 动态设置搜索查询【英文标题】:Algolia vue instantsearch dynamically set search query 【发布时间】:2021-05-08 16:28:52 【问题描述】:

我在根组件 (App.vue) 上有一个搜索栏。我想输入一个查询,在@keyup.enter 上,它应该重定向到Search 组件视图,并带有v-text-field 输入值。使用$router.replace 进行重定向是因为用户可能会在同一路由中搜索不同的关键字。

下面的代码有效,但只有 ONCE。如果我输入新的搜索词,URL 会发生变化,但结果保持不变。

App.vue

<template>
  <div>
    <header>
      <v-text-field @keyup.enter="goToSearchPage($event)"></v-text-field>
    </header>
    <v-main>
      <router-view></router-view>
    </v-main>
  </div>
</template>
 <script>
    export default 
      methods: 
        goToSearchPage($event) 
          this.$router.replace(
            name: "Search",
            query:  q: $event.target.value 
          );
        
      
    ;
    </script>

views/Search.vue

<template>
  <div>
    <ais-instant-search
      index-name="dev_brunjar_products"
      :search-client="searchClient"
      :search-function="searchFunction"
    >
      <ais-hits>
        <ul slot-scope=" items ">
          <li v-for="item in items" :key="item.objectID">
             item.name 
          </li>
        </ul>
      </ais-hits>
    </ais-instant-search>
  </div>
</template>

<script>
import algoliasearch from "algoliasearch/lite";

export default 
  data() 
    return 
      searchClient: algoliasearch(
        process.env.VUE_APP_ALGOLIA_APP_ID,
        process.env.VUE_APP_ALGOLIA_SEARCH_KEY
      )
    ;
  ,
  methods: 
    // According to Algolia's doc, this should be inside data instead of methods
    // https://www.algolia.com/doc/api-reference/widgets/instantsearch/vue/#widget-param-search-function
    // But doing so, I wouldn't be able to get this.$route.query.q
    searchFunction(helper) 
      var query = this.$route.query.q;

      if (query) 
        helper.setQuery(query).search();
      
    
  
;
</script>

我尝试过的

做了一个 hack-ish 方法(测试 1)来解决它,但没有奏效(我很高兴,因为它感觉不对)。下面是对搜索组件的非工作代码添加。创建 query 的计算和监视属性,当 searchFunction 首次加载时,它从 this.$route.query.qalgoliaHelper 分配给 AlgoliaSearchHelper 的数据获取数据。

当我输入一个新的搜索词时,观察者工作并且查询确实发生了变化。尽管如此,调用助手并在观察者中使用新术语设置其查询并没有改变来自 Algolia 的结果。

然后我使用Routing URLs(测试2)到ais-instant-search,它仍然没有解决问题。也许我实施错了?我真的很想理解 Algolia 的文档,但它太难消化了。

views/Search.vue - 测试 1(失败)

<template>
  <div>
    <ais-instant-search
      index-name="dev_brunjar_products"
      :search-client="searchClient"
      :search-function="searchFunction"
    >
      <ais-hits>
        <ul slot-scope=" items ">
          <li v-for="item in items" :key="item.objectID">
             item.name 
          </li>
        </ul>
      </ais-hits>
    </ais-instant-search>
  </div>
</template>

<script>
import algoliasearch from "algoliasearch/lite";

export default 
  data() 
    return 
      searchClient: algoliasearch(
        process.env.VUE_APP_ALGOLIA_APP_ID,
        process.env.VUE_APP_ALGOLIA_SEARCH_KEY
      ),
      algoliaHelper: null
    ;
  ,
  computed: 
    query() 
      return this.$route.query.q;
    
  ,
  watch: 
    query(newQuery) 
      this.algoliaHelper.setQuery(newQuery).search();
    
  ,
  methods: 
    searchFunction(helper) 
      if (!this.algoliaHelper) 
        this.algoliaHelper = helper;
      

      if (this.query) 
        helper.setQuery(this.query).search();
      
    
  
;
</script>

views/Search.vue - 测试 2(失败)

<template>
  <div>
    <ais-instant-search
      index-name="dev_brunjar_products"
      :search-client="searchClient"
      :search-function="searchFunction"
      :routing="routing"
    >
      <ais-hits>
        <ul slot-scope=" items ">
          <li v-for="item in items" :key="item.objectID">
             item.name 
          </li>
        </ul>
      </ais-hits>
    </ais-instant-search>
  </div>
</template>

<script>
import  history as historyRouter  from "instantsearch.js/es/lib/routers";
import  singleIndex as singleIndexMapping  from "instantsearch.js/es/lib/stateMappings";
import algoliasearch from "algoliasearch/lite";

export default 
  data() 
    return 
      searchClient: algoliasearch(
        process.env.VUE_APP_ALGOLIA_APP_ID,
        process.env.VUE_APP_ALGOLIA_SEARCH_KEY
      ),
      routing: 
        router: historyRouter(),
        stateMapping: singleIndexMapping("instant_search")
      
    ;
  ,
  methods: 
    searchFunction(helper) 
      if (this.query) 
        helper.setQuery(this.query).search();
      
    
  
;
</script>

如果你们知道如何解决这个问题,我将不胜感激。

【问题讨论】:

【参考方案1】:

https://codesandbox.io/s/github/algolia/doc-code-samples/tree/master/Vue%20InstantSearch/routing-vue-router?file=/src/views/Home.vue

这是一个使用 vue 路由器的例子。我想这可能是你正在寻找的。 请让我们知道它是否适合您。

【讨论】:

嘿@eunjae.lee,感谢您的回答。虽然,我已经找到了一个简单的解决方案。我使用&lt;ais-search-box v-show="false" :value="this.$route.query.q" /&gt;,效果很好。在性能和最佳实践方面,我不确定使用该方法会丢失什么。为什么我应该实现路由道具? 嘿@AfiqRosli,不,如果它适用于您,那就没问题。该示例仅向您展示如何根据需要自定义路由。

以上是关于Algolia vue Instantsearch 动态设置搜索查询的主要内容,如果未能解决你的问题,请参考以下文章

Algolia instantsearch.js:如何获取所有方面

渲染搜索结果后,Algolia 在 Instantsearch 中显示所有搜索参数

没有 UI 的 Algolia 搜索

如何以角度从 algolia 获取特定数据

仅当搜索框不为空时才显示项目匹配内容

html Vue InstantSearch - 无限滚动示例