algolia / vue-instantsearch

👀 Algolia components for building search UIs with Vue.js
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/vue
MIT License
854 stars 157 forks source link

Button with on:click event, ais-sort-by component reset #1116

Closed bmpf closed 2 years ago

bmpf commented 2 years ago

Bug 🐞

What is the current behavior?

When there are buttons in the page, the ais-sort-by component reset.

Make a sandbox with the current behavior

Sandbox Code (just copy and past in sandox link) Template: https://codesandbox.io/s/github/algolia/create-instantsearch-app/tree/templates/vue-instantsearch

<template>
  <div>
    <header class="header">
      <h1 class="header-title">
        <a href="/">
          vue-instantsearch-app
        </a>
      </h1>
      <p class="header-subtitle">
        using
        <a href="https://github.com/algolia/vue-instantsearch">
          Vue InstantSearch
        </a>
      </p>
    </header>
    <button v-on:click="open = !open" v-bind:class="[open ? 'bg-gray-600' : 'bg-indigo-600']" class="mt-5 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white hover:bg-gray-600 w-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Definições</button>

    <div class="container">
      <ais-instant-search :search-client="searchClient" index-name="instant_search">
        <div class="search-panel">
          <div class="search-panel__filters">
            <ais-refinement-list attribute="brand" />
          </div>
          <div>
                <ais-sort-by
                    :class-names="{
                        'ais-SortBy': '',
                        'ais-SortBy-select': '',
                        'ais-SortBy-option' : ''
                    }"
                    :items="[
    { value: 'instant_search', label: 'Featured' },
    { value: 'instant_search_price_asc', label: 'Price asc.' },
    { value: 'instant_search_price_desc', label: 'Price desc.' },
  ]"
                />
                </div>
          <div class="search-panel__results">
            <div class="searchbox">
              <ais-search-box placeholder="" />
            </div>
            <ais-hits>
              <template slot="item" slot-scope="{ item }">
                <article>
                  <h1>
                    <ais-highlight :hit="item" attribute="name" />
                  </h1>
                  <p>
                    <ais-highlight :hit="item" attribute="description" />
                  </p>
                </article>
              </template>
            </ais-hits>

            <div class="pagination">
              <ais-pagination />
            </div>
          </div>
        </div>
      </ais-instant-search>
    </div>
  </div>
</template>

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

export default {
  data() {
    return {
      open: false,
      searchClient: algoliasearch('latency', '6be0576ff61c053d5f9a3225e2a90f76'),
    };
  },
};
</script>

<style>
body,
h1 {
  margin: 0;
  padding: 0;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica,
    Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}

em {
  background: cyan;
  font-style: normal;
}

.header {
  display: flex;
  align-items: center;
  min-height: 50px;
  padding: 0.5rem 1rem;
  background-image: linear-gradient(to right, #4dba87, #2f9088);
  color: #fff;
  margin-bottom: 1rem;
}

.header a {
  color: #fff;
  text-decoration: none;
}

.header-title {
  font-size: 1.2rem;
  font-weight: normal;
}

.header-title::after {
  content: ' ▸ ';
  padding: 0 0.5rem;
}

.header-subtitle {
  font-size: 1.2rem;
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 1rem;
}

.search-panel {
  display: flex;
}

.search-panel__filters {
  flex: 1;
}

.search-panel__results {
  flex: 3;
}

.searchbox {
  margin-bottom: 2rem;
}

.pagination {
  margin: 2rem auto;
  text-align: center;
}
</style>

https://user-images.githubusercontent.com/33966960/155701250-f1fa222b-d8e0-42c4-a501-1c5679f4643b.mp4

What is the expected behavior?

ais-sort-by value cannot change.

Does this happen only in specific situations?

When there is a button in the page and it is clicked.

What is the version you are using?

Latest

Haroenv commented 2 years ago

When you put an inline object or array, it will reset when there's a change in the vue state, as it's re-rendering.

Change :items="[...]" to :items="myItems" (same for cssClasses), and use those values from data instead.

Unfortunately this is a limitation of Vue we haven't yet found a solution for.

bmpf commented 2 years ago

The answer provided by @Haroenv fix the problem.