首页 > 解决方案 > 如何在 vuejs 中正确分页?

问题描述

我遇到的问题是我的分页器总是显示的值total: items.length等于 20,这是不正确的,我使用的是我实现的自定义 api,它的数据超过 10 页,所以总数不可能是 20数据。

开发工具

在这里,我展示了 devtool 中的输出,清楚地表明我的 API 的端点有超过 10 页的数据。

如果您注意到,它只会说您只有 20 个数据,这是不可能的。

data: (10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, __ob__: Observer]
next_page: 2
page: 1
per_page: 10
pre_page: null
total: 20
total_pages: 2

我会感谢你的帮助。

分页

export const paginator = (items, page, per_page) => {
  var page = page || 1,
  per_page = per_page || 10,
  offset = (page - 1) * per_page,

  paginatedItems = items.slice(offset).slice(0, per_page),
  total_pages = Math.ceil(items.length / per_page),

  paginContent = {
    page: page,
    per_page: per_page,
    pre_page: page - 1 ? page - 1 : null,
    next_page: (total_pages > page) ? page + 1 : null,
    total: items.length,
    total_pages: total_pages,
    data: paginatedItems
  };
  console.log("Paginate Item: ", paginatedItems);
  console.log("Pagin Content: ", paginContent);
  return paginContent.data;
};

Actions.js

 GET_ANIME_ALPHA({commit} , info){
    A.get(`${API_URL_ENDPOINT.letter}` + "/" + info.letter + "/" + info.page)
      .then((res) =>{
        const animes = res.data.animes;
        //console.log("\n⚠️ ANIME BY LETTER (res): " , animes);
        const dataPaginated = pagin.paginator(animes , info.page , 10);
        commit('SET_ANIME_ALPHA' , dataPaginated);
        commit('IS_LOADING' , false);
      }).then((err) =>{
        console.log(err);
    });
  },

AnimeByLetters.vue

<template>
  <!-- all content -->
  <div class="flex-1 flex flex-col bg-white overflow-hidden">
    <!-- top bar -->
    <div class="border-b flex px-6 py-2 items-center flex-none">
        <div class="flex flex-col">
            <h3 class="text-grey-darkest mb-1 font-extrabold"> Animes by Letter</h3>
            <div class="text-grey-dark text-sm truncate">
               Enjoy the world of anime 
            </div>
        </div>

        <div class="flex-1 justify-center hidden sm:flex">

        </div>
        <!-- href links to platforms and social media -->
        <div class="flex justify-start items-center text-gray-500">
          <h1>Alphabet</h1>
          <select class="list-reset border border-purple-200 rounded m-3 w-20 font-sans" v-model="letter">
            <option v-for="(char , index) in options"
              :value="char"
              :key="index"
            >
              {{char}}
            </option>
          </select>

          <a href="https://github.com/ChrisMichaelPerezSantiago/ryuanime" class="block flex items-center hover:text-gray-700 mr-5">
            <svg class="fill-current w-5 h-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
              <title>GitHub</title>
              <path d="M10 0a10 10 0 0 0-3.16 19.49c.5.1.68-.22.68-.48l-.01-1.7c-2.78.6-3.37-1.34-3.37-1.34-.46-1.16-1.11-1.47-1.11-1.47-.9-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.9 1.52 2.34 1.08 2.91.83.1-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.94 0-1.1.39-1.99 1.03-2.69a3.6 3.6 0 0 1 .1-2.64s.84-.27 2.75 1.02a9.58 9.58 0 0 1 5 0c1.91-1.3 2.75-1.02 2.75-1.02.55 1.37.2 2.4.1 2.64.64.7 1.03 1.6 1.03 2.69 0 3.84-2.34 4.68-4.57 4.93.36.31.68.92.68 1.85l-.01 2.75c0 .26.18.58.69.48A10 10 0 0 0 10 0">
              </path>
            </svg> 
          </a>
        </div>
    </div>


    <!-- content inside -->
    <div class="px-6 py-4 flex-1 overflow-y-scroll scrollbar" id="style-1">
      <div v-if="isLoading">
        <div class="lds-roller"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
      </div>
      <div class="flex flex-wrap" v-else>
        <div class="w-full sm:w-1/2 md:w-1/2 lg:w-1/2 xl:w-1/2 mb-4" v-for="(anime , index) in animesByAlpha" :key="index">
          <LatestAnime :anime="anime"/>
        </div>
      </div>
    </div>

     <paginate
      class="paginator-container list-reset border border-purple-200 rounded w-auto font-sans"
      v-model="page"
      :page-count="animesByAlpha.length"
      :page-range="3"
      :margin-pages="2"
      :click-handler="pageHandler"
      :prev-text="'Prev'"
      :next-text="'Next'"
      :container-class="'pagination'"
      :page-class="'page-item'">
    </paginate>


    <!-- footer -->
    <Footer/>

  </div>
</template>

<script>
  import Footer from "./Footer"
  import LatestAnime from '../components/LatestAnime'
  import {mapState , mapGetters} from 'vuex'
  import store from '../store/store'

  export default {
    name: "AnimesByLetter",
    components:{
      LatestAnime,
      Footer
    },
    data(){
      return{
        page: 0,
        searchModel: '',
        letter: "a",
        options: [...Array(26).keys()].map(i => String.fromCharCode(i + 97)) //[a .. z]
      }
    },
    computed:{
      ...mapState(['animesByAlpha' , 'isLoading']),
    },
    watch:{
      "letter": function(value){
        this.letter = value;
        let letter = this.letter;
        let info = {letter: letter , page: this.page}
        store.dispatch('GET_ANIME_ALPHA' , info);
      }
    },
    created(){
      let info = {letter: this.letter , page: this.page}
      store.dispatch('GET_ANIME_ALPHA' , info)
    },
    methods:{
      pageHandler(){
        try{
          let info = {letter: this.letter , page: this.page}
          store.dispatch('GET_ANIME_ALPHA' , info)
        }catch(err){
          console.log(err);
        }
      }
    }
  };
</script>

标签: javascriptvue.jspaginationvuex

解决方案


推荐阅读