M
M
Maxim js2021-04-17 13:32:24
Design
Maxim js, 2021-04-17 13:32:24

How to make vue vuex axios pagination work?

Hello good people, please tell me the code, or a link where to read how to work with pagination in api.
I got now data from 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"
    },
    // ...
  ]
}

now I'm displaying 20 heroes on the page,
<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,
    }
})

it turns out I have access to the data
"count": 671,
    "pages": 34,
    "next": "https://rickandmortyapi.com/api/character/?page=20",
    "prev": "https://rickandmortyapi.com/api/character/?page=18"

how to blind full-fledged pagination with them, I use pagination https://element-plus.org/#/en-US/component/pagination

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
Svetlana Larchenko, 2018-07-17
@SvetlanaLN

Hello.
You would have at least some sketch for an example, well, on the same note sheet with a pencil, and posted the photo here.
And on the topic, I recommend doing animation in SVG using the free Inkscape
. This is to the fact that not only do you not have to painfully puzzle over CSS, and look at the "Object Interactivity" screenshot.
5b4dbf9a60b01073818606.png

S
Sergey Panteleev, 2018-07-17
@s_panteleev

And what radio buttons do not suit? All cuteness is up to you :)

<style>
    .gender__item input[type=radio] {
        display: none;
    }
    .gender__item input[type=radio] + .gender__name {
        // обычное состояние
    }
    .gender__item input[type=radio]:checked + .gender__name {
        // выбранное состояние
    }
</style>
<div class="gender">
    <label for="gender_m" class="gender__item">
        <input type="radio" name="gender" value="m" id="gender_m" />
        <span class="gender__name">Мужской</span>
    </label>
    <label for="gender_f" class="gender__item">
        <input type="radio" name="gender" value="f" id="gender_f" />
        <span class="gender__name">Женский</span>
    </label>
</div>

0
0xD34F, 2021-04-17
@winers

Let the store, in addition to the data array itself, also store the current page and the total number of pages; fetchCharacters action - let it load not the default first page, but which one will be specified:

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);
    }
  },
},

In the component where pagination is used, we make a calculated property that will be responsible for the current page - the getter gets the value from the store, the setter calls the fetchCharacters action:
computed: {
  currentPage: {
    get() {
      return this.$store.state.page;
    },
    set(page) {
      this.$store.dispatch('fetchCharacters', page);
    },
  },
},

Bind this computed property to the pagination component instance:
<el-pagination
  v-model:current-page="currentPage"
  :page-count="$store.state.pages"
  layout="prev, pager, next"
  background
/>

https://jsfiddle.net/4a1qmjc5/

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question