【问题标题】:Algolia vue instantsearch dynamically set search queryAlgolia vue Instantsearch 动态设置搜索查询
【发布时间】: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>

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

【问题讨论】:

    标签: javascript vue.js vuejs2 algolia vue-instant-search


    【解决方案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,不,如果它适用于您,那就没问题。该示例仅向您展示如何根据需要自定义路由。
    猜你喜欢
    • 2019-01-06
    • 2018-03-30
    • 1970-01-01
    • 2020-11-15
    • 1970-01-01
    • 2021-09-05
    • 2021-09-02
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多