@winers
Начинающий программист

Как заставить работать пагинацию?

Получаю данные с api.
{
  "info": {
    "count": 671,
    "pages": 34,
    "next": "https://rickandmortyapi.com/api/character/?page=20",
    "prev": "https://rickandmortyapi.com/api/character/?page=18"
  },
  "results": [
    {
      "id": 361,
      "name": "Toxic Rick",
      "status": "Dead",
      "species": "Humanoid",
      "type": "Rick's Toxic Side",
      "gender": "Male",
      "origin": {
        "name": "Alien Spa",
        "url": "https://rickandmortyapi.com/api/location/64"
      },
      "location": {
        "name": "Earth",
        "url": "https://rickandmortyapi.com/api/location/20"
      },
      "image": "https://rickandmortyapi.com/api/character/avatar/361.jpeg",
      "episode": [
        "https://rickandmortyapi.com/api/episode/27"
      ],
      "url": "https://rickandmortyapi.com/api/character/361",
      "created": "2018-01-10T18:20:41.703Z"
    },
    // ...
  ]
}


Вывожу на страницу 20 записей.
<template>
    <div class="main">
        <el-pagination
            background
            layout="prev, pager, next"
            :total="1000">
        </el-pagination>
        <div class="main__inner">
            <Card v-for="character in characters" :key="character.id" :character="character"/>
        </div>
    </div>
</template>

<script>
import Card from '@/components/Card.vue'
import {mapState} from "vuex";

export default {
    name: 'Main',
    components: {
        Card,
    },
    computed: {
        ...mapState(['characters'])
    },
    created() {
        this.$store.dispatch('fetchCharacters')
    },
}
</script>

store
import {createStore} from 'vuex'
import axios from "axios";

const baseURL = 'https://rickandmortyapi.com/api/character';

export default createStore({
    state: {
        characters: [],
    },
    mutations: {
        SET_CHARACTERS(state, payload) {
            state.characters = payload;
        }
    },
    actions: {
        fetchCharacters(state) {
            return axios.get(`${baseURL}`)
                .then(({data}) => {
                    state.commit('SET_CHARACTERS', data.results)
                })
                .catch(error => console.log(error));
        }
    },
    getters: {
        getCharacters: state => state.characters,
    }
})

Получается, у меня есть доступ к данным:

"count": 671,
"pages": 34,
"next": "https://rickandmortyapi.com/api/character/?page=20",
"prev": "https://rickandmortyapi.com/api/character/?page=18"

Как с ними слепить полноценную пагинацию? Используемый компонент пагинации - https://element-plus.org/en-US/component/paginatio...
  • Вопрос задан
  • 219 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Vue.js
Пусть в сторе кроме собственно массива данных также хранятся текущая страница и общее количество страниц; действие fetchCharacters - пусть загружает не дефолтную первую страницу, а какую будет указано:

state: {
  characters: [],
  page: 0,
  pages: 0,
},
mutations: {
  setCharacters: (state, { characters, pages, page }) =>
    Object.assign(state, { characters, pages, page }),
},
actions: {
  async fetchCharacters({ commit }, page = 1) {
    try {
      const { data: { info, results } } = await axios.get(`${BASE_URL}?page=${page}`);
      commit('setCharacters', {
        page,
        pages: info.pages,
        characters: results,
      });
    } catch (e) {
      console.error(e);
    }
  },
},

В компоненте, где используется пагинация, делаем вычисляемое свойство, которое будет отвечать за текущую страницу - геттер достаёт значение из стора, сеттер вызывает действие fetchCharacters:

computed: {
  currentPage: {
    get() {
      return this.$store.state.page;
    },
    set(page) {
      this.$store.dispatch('fetchCharacters', page);
    },
  },
},

Привязываем это вычисляемое свойство к экземпляру компонента пагинации:

<el-pagination
  v-model:current-page="currentPage"
  :page-count="$store.state.pages"
  layout="prev, pager, next"
  background
/>

https://jsfiddle.net/qbjc9onm/
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы