Понимание того, как использовать нумерацию страниц в Bootstrap - vue - PullRequest
0 голосов
/ 01 марта 2020

Я написал следующий код:

<div>
    <div id="app" class="container">
        <div class="grid">
            <article v-for="tool in tools">
                <div class="title">
                    <h3>{{capitalizeFirstLetter(tool.name)}}</h3>
                </div>
                <div class="description">
                    {{tool.description}}
                </div>
                <br>
                <div>
                    <toggle-button :value=tool.status color="#82C7EB" :width=100 :height=30 :sync="true" :labels="{checked: 'Following', unchecked: 'Unfollowing'}" @change="onChange(tool)"/>
                </div>
            </article>
        </div>
    </div>
</div>

Недавно я начал использовать Bootstrap - Vue. Я пытаюсь понять, как добавить нумерацию страниц внизу. Я не уверен, как работает aria-controls. Моя цель - иметь 9 блоков tools на каждой странице. Как мне добавить нумерацию страниц, чтобы я мог перейти к следующим 9 блокам tools?

1 Ответ

1 голос
/ 02 марта 2020

Поскольку было неясно, нужна ли вам нумерация страниц на стороне клиента или на стороне сервера, я сделал пример того и другого в фрагменте.

Для простоты я сделал это по 3 на страницу, но вы можете изменить его на 9.

Первый получает начальную страницу при загрузке, а затем вызывает API каждый раз, когда страница изменяется, используя watcher, который вызывает метод с новой страницей, который затем извлекает это место и заменяет наши старые данные новыми.

Второй загружает все данные при загрузке страницы и вместо этого разбивает массив данных на основе свойства per_page, так что отображаются только элементы для этой страницы. Для этого я использовал вычисляемое свойство, которое автоматически обновляется на основе свойств, используемых внутри него.

Обе страницы имеют значение aria-controls, определенное id контейнера наших элементов страницы. Это используется, чтобы сообщить программам чтения с экрана, какие элементы изменяет пагинация.

Классы row, col-*, border, mx-auto, h2 и text-center - это классы, используемые для стилизации и макет и не является частью фактического решения, поэтому вы можете свободно изменять или удалять их.

new Vue({
  el: '#app',
  computed: {
    pagination2CurrentItems() {
      const startIndex = (this.pagination2.current_page - 1) * this.pagination2.per_page;
      const endIndex = startIndex + this.pagination2.per_page;
      return this.pagination2.items.slice(startIndex, endIndex)
    }
  },
  created() {
    this.getPagination1Data()
    this.getPagination2Data()
  },
  filters: {
    capitalizeFirstLetter(value) {
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  },
  data() {
    return {
      pagination1: {
        items: [],
        per_page: 3,
        total_rows: 0,
        current_page: 1
      },
      pagination2: {
        items: [],
        per_page: 3,
        total_rows: 0,
        current_page: 1
      }
    }
  },
  methods: {
    getPagination1Data(page = 1) {
      fetch(`https://reqres.in/api/unknown?page=${page}&per_page=3`)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          this.pagination1.total_rows = data.total;
          this.pagination1.items = data.data;
        });
    },
    getPagination2Data() {
      /*  
        This endpoint only has 12 items total, 
        so this will get all in one call
      */
      fetch(`https://reqres.in/api/unknown?per_page=12`)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          this.pagination2.total_rows = data.total;
          this.pagination2.items = data.data;
        });
    }
  },
  watch: {
    'pagination1.current_page'(newPage) {
      this.getPagination1Data(newPage)
    }
  }
})
<script src="https://unpkg.com/vue@2.6.11/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue@2.5.0/dist/bootstrap-vue.js"></script>

<link href="https://unpkg.com/bootstrap@4.4.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://unpkg.com/bootstrap-vue@2.5.0/dist/bootstrap-vue.css" rel="stylesheet"/>

<div id="app" class="container">
  <div id="tools_list_1" class="row">
    <div class="col-12 h2 text-center">
     Server pagination
    </div>
    <article class="col-3 mx-auto border" v-for="tool in pagination1.items">
      <div class="title">
        <h3>{{ tool.name | capitalizeFirstLetter }}</h3>
      </div>
      <div class="description">
        {{ tool.pantone_value }}
      </div>
    </article>
  </div>
  <div class="row mt-2">
    <div class="col-12">
      <b-pagination
        v-model="pagination1.current_page"
        :per-page="pagination1.per_page"
        :total-rows="pagination1.total_rows"
        aria-controls="tools_list_1"
        >
      </b-pagination>
    </div>
  </div>
  <div id="tools_list_2" class="row">
    <div class="col-12 h2 text-center">
      Client pagination
    </div>
    <article class="col-3 mx-auto border" v-for="tool in pagination2CurrentItems">
      <div class="title">
        <h3>{{ tool.name | capitalizeFirstLetter }}</h3>
      </div>
      <div class="description">
        {{ tool.pantone_value }}
      </div>
    </article>
  </div>
  <div class="row mt-2">
    <div class="col-12">
      <b-pagination
        v-model="pagination2.current_page"
        :per-page="pagination2.per_page"
        :total-rows="pagination2.total_rows"
        aria-controls="tools_list_2"
        >
      </b-pagination>
    </div>
  </div>
</div>
...