Algolia vue Instantsearch динамически устанавливает поисковый запрос

У меня есть панель поиска в корневом компоненте (App.vue). Я хочу ввести запрос, и на @keyup.enter он должен перенаправить на Search представление компонента с входным значением v-text-field. Перенаправление используется с использованием $router.replace, потому что пользователи могут искать другое ключевое слово в пределах одного и того же маршрута.

Приведенный ниже код работает, но только ОДИН РАЗ. Если я введу новый поисковый запрос, 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>

просмотры / 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>

Что я пробовал

Сделал хакерский способ (Тест 1), чтобы решить эту проблему, но не сработал (чему я рад, потому что это кажется неправильным). Ниже был нерабочий код, добавленный к компоненту поиска. Создано свойство computed & watch для query, которое получает свои данные из данных this.$route.query.q и algoliaHelper, назначенных с помощью AlgoliaSearchHelper при первой загрузке searchFunction.

Когда я ввел новый поисковый запрос, наблюдатель работает, и запрос действительно изменился. Несмотря на это, вызов помощника и установка его запроса с новым термином в наблюдателе не повлияли на результаты Algolia.

Затем я использовал Маршрутизация URL-адресов (тест 2) на ais-instant-search, но проблема все еще не решена. Может я неправильно реализую? Я действительно пытался понять документ Алголии, но его слишком сложно переварить.

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>

Буду признателен, если вы, ребята, знаете, как решить эту проблему.


person Afiq Rosli    schedule 04.02.2021    source источник


Ответы (1)


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

Это пример использования vue router. Думаю, это может быть то, что вы ищете. Сообщите нам, работает ли это для вас.

person eunjae.lee    schedule 08.02.2021
comment
Привет, @ eunjae.lee, спасибо за ответ. Хотя, я уже нашел себе простое решение. Я использую <ais-search-box v-show="false" :value="this.$route.query.q" />, и он отлично работает. Что касается производительности и лучших практик, я не уверен, что теряется при использовании этого подхода. Есть ли причина, по которой я должен вместо этого реализовать реквизиты маршрутизации? - person Afiq Rosli; 09.02.2021
comment
Привет @AfiqRosli, нет, если у тебя работает, то нормально. Этот пример просто показывает вам, как настроить маршрутизацию, если вам нужно. - person eunjae.lee; 10.02.2021