У меня есть панель поиска в корневом компоненте (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>
Буду признателен, если вы, ребята, знаете, как решить эту проблему.