Разбивка на страницы

Разбивка на страницы может быть очень полезным инструментом при работе с большими наборами данных. Если у вас есть 1000 опций, компонент будет отображать 1000 узлов DOM. Это очень много узлов для вставки/удаления, и, скорее всего, вашего пользователя в любом случае интересуют только некоторые из них.

Чтобы реализовать разбиение на страницы с помощью Vs Vue3 Select, вы можете воспользоваться слотом list-footer. Он отображается под всеми другими параметрами в выпадающем списке.

Чтобы разбиение на страницы корректно работало с фильтрацией, вам придется самостоятельно обработать ee в родительском компоненте. Вы можете использовать логическое значение filterable, чтобы отключить фильтрацию Vs Vue3 Select, а затем подключиться к событию search, чтобы использовать текущий поисковый запрос в родительском компоненте.

<template>
  <v-select
    :options="paginated"
    :filterable="false"
    @search="(query) => (search = query)"
  >
    <template #list-footer>
      <li class="pagination">
        <button :disabled="!hasPrevPage" @click.prevent="offset -= limit">
          Prev
        </button>
        <button :disabled="!hasNextPage" @click.prevent="offset += limit">
          Next
        </button>
      </li>
    </template>
  </v-select>
</template>

<script>
import countries from '../data/countries'

export default {
  data: () => ({
    countries,
    search: '',
    offset: 0,
    limit: 5,
  }),
  computed: {
    filtered() {
      return this.countries.filter((country) =>
        country.toLocaleLowerCase().includes(this.search.toLocaleLowerCase()),
      )
    },
    paginated() {
      return this.filtered.slice(this.offset, this.limit + this.offset)
    },
    hasNextPage() {
      const nextOffset = this.offset + this.limit
      return Boolean(
        this.filtered.slice(nextOffset, this.limit + nextOffset).length,
      )
    },
    hasPrevPage() {
      const prevOffset = this.offset - this.limit
      return Boolean(
        this.filtered.slice(prevOffset, this.limit + prevOffset).length,
      )
    },
  },
  methods: {
    onSearch(query) {
      this.search = query
      this.offset = 0
    },
  },
}
</script>

<style scoped>
.pagination {
  display: flex;
  margin: 0.25rem 0.25rem 0;
}
.pagination button {
  flex-grow: 1;
}
.pagination button:hover {
  cursor: pointer;
}
</style>