vue bootstrap 分頁,可自定義按鈕操作函數,自動監測每頁數據數量修改,可修改分頁元素顯示數量

vue bootstrap有一個很強大的組件bootstrap-vue。但是這個組件的分頁貌似并不支持前后端分離的分頁。
我至少是沒看出來。如果有看出來的請告訴我。
如果有用這個組件的同學可以跟我交流。
QQ:871966163
直通車bootstrap-vue

自己寫了個分頁組件,開箱即用。如有bug歡迎留言。
嫌麻煩大佬可以直通github,clone項目直接使用
vue-bootstrap-pagination

另外封裝了一個 渲染函數&jsx的分頁組件,有需要可以加QQ交流
jsx
組件

1、 參數

(1)props參數
  • total:數據總數,這個是必傳參數。比如總數據有1000條,10000條。 數量為0,負數或者非數字字符串時,total取值為1,也就是最小值為1

  • size: 每一頁的數據條數。比如每一頁顯示10條,15條。 數字為0,負數或者非數字字符串時,size取值為10

  • currentPage:分頁初始頁碼,就是第一次進入有分頁的這個頁面顯示的頁碼。記住是第一次數字為0,附屬或者為非數字字符串時,currentPage取值為1,也就是最小值為1

這個數據是可以在操作分頁的時候修改的,方便 vuex 記住當前頁面,然后賦值初始頁面,實現在第 N 頁查看某一條數據進入另一個頁面回來時還是會停留在第 N 頁的效果,或者看到第 N 頁了,點擊其他頁面,再點擊回來,仍然會停留在第 N 頁。

這個功能需要配合 \color{red}{getCurrentPage}

  • limit:分頁元素。分頁條顯示的元素數量。數字小于5或者為非數字字符串時,limit取值為5,也就是最小值為5
    比如limit=5,會顯示如下:
    分頁元素為5

    分頁條數為5

    分頁條數為5

也就是除了左右兩邊箭頭按鈕會顯示的分頁元素數量

  • \color{blue}{align}:分頁位置, left:左邊,center:居中, right:右邊。默認在左邊

    左邊

    align=center
    中間

    align=right
    右邊.png

  • firstFunction:點擊跳轉到第一頁觸發函數

  • prevFunction:上一頁按鈕觸發函數

  • currentFunction:點擊頁碼觸發函數

  • nextFunction:下一頁按鈕觸發函數

  • lastFunction:最后一頁按鈕觸發函數

  • sizeFunction:改變每頁數量觸發函數

  props: {
    //總數據
    total: {
      type: [Number, String],
      required: true
    },
    // 每頁數量
    size: {
      type: [Number, String],
      default: 10
    },
    // 初始頁碼
    currentPage: {
      type: [Number, String],
      default: 1
    },
    // 分頁顯示數量
    limit: {
      type: [Number, String],
      default: 5
    },
    // 分頁位置
    align: {
      default: "left",
      type: String
    },
    // 跳轉第一頁按鈕觸發函數
    firstFunction: {
      type: Function,
      required: true
    },
    // 上一頁按鈕觸發函數
    prevFunction: {
      type: Function,
      required: true
    },
    // 點擊頁碼觸發函數
    currentFunction: {
      type: Function,
      required: true
    },
    // 下一頁按鈕觸發函數
    nextFunction: {
      type: Function,
      required: true
    },
    // 最后一頁按鈕觸發函數
    lastFunction: {
      type: Function,
      required: true
    },
    // 修改每頁數量觸發函數
    sizeFunction: {
      type: Function
    }
  },
(2)data參數
  • tempalteCurrentPage:分頁當前頁碼。也就是激活的頁碼
  data() {
    return {
      tempalteCurrentPage: ""
    };
  },

2、 方法methods

  • toInteger:字符串轉為數字類型
  • _firstFunction:跳轉第一頁按鈕觸發函數
  • _prevFunction:上一頁按鈕觸發函數
  • _currentFunction:點擊頁碼觸發函數
  • _nextFunction:下一頁按鈕觸發函數
  • _lastFunction:最后一頁按鈕觸發函數
  • _sizeFunction:修改每頁數量觸發函數
  methods: {
    // 字符串轉為數字類型 因為props會接收字符串,所以需要進行轉換
    toInteger(val) {
      return parseInt(val, 10);
    },
    // 跳轉第一頁按鈕觸發函數
    _firstFunction() {
      if (this.firstFunction) {
        this.tempalteCurrentPage = 1;
        this.firstFunction();
      }
    },
    // 上一頁按鈕觸發函數
    _prevFunction() {
      if (this.prevFunction) {
        this.tempalteCurrentPage = this.tempalteCurrentPage - 1;
        this.prevFunction();
      }
    },
    // 點擊頁碼觸發函數
    _currentFunction(item) {
      if (this.currentFunction) {
        this.tempalteCurrentPage = item;
        this.currentFunction();
      }
    },
    // 下一頁按鈕觸發函數
    _nextFunction() {
      if (this.nextFunction) {
        this.tempalteCurrentPage = this.tempalteCurrentPage + 1;
        this.nextFunction();
      }
    },
    // 最后一頁按鈕觸發函數
    _lastFunction() {
      if (this.lastFunction) {
        this.tempalteCurrentPage = this.nlyPgPages;
        this.lastFunction();
      }
    },
    // 修改每頁數量觸發函數
    _sizeFunction() {
      if (this.sizeFunction) {
        this.sizeFunction();
      }
    },
    // 分頁元素添加上一頁,最后一頁,第一頁,下一頁等按鈕
    _tempalteArray() {
      // this.nlyPgItemArray為 computed 中 nlyPgItemArray屬性
      let nlyPgItemArrayAll = this.nlyPgItemArray;
      nlyPgItemArrayAll.splice(0, 0, "?");
      nlyPgItemArrayAll.splice(0, 0, "??");
      nlyPgItemArrayAll.push("?");
      nlyPgItemArrayAll.push("??");

      return nlyPgItemArrayAll;
    }
  },

3、 計算屬性computed

  • nlyPgTotal:轉換總頁轉為數字類型
  • nlyPgSize:每頁數量轉為數字類型
  • nlyPgCurrentPage:當前頁數轉為數字類型
  • nlyPgLimit:分頁顯示元素轉為數字類型
  • nlyPgPages:計算總頁數
  • nlyPgItemArray: 生成不包括上一頁,下一頁等按鈕的分頁元素
  • alignClass:分頁位置
  • tempalteArray:生成包括最后一頁,上一頁,第一頁,下一頁等按鈕的元素,最終分頁元素
  computed: {
    // 轉換總頁轉為數字類型
    nlyPgTotal: function() {
      return isNaN(this.toInteger(this.total))
        ? 1
        : this.toInteger(this.total) <= 0
        ? 1
        : this.toInteger(this.total);
    },
    // 每頁數量轉為數字類型
    nlyPgSize: function() {
      return isNaN(this.toInteger(this.size))
        ? 10
        : this.toInteger(this.size) <= 0
        ? 10
        : this.toInteger(this.size);
    },
    // 當前頁數轉為數字類型
    nlyPgCurrentPage: function() {
      return this.toInteger(this.tempalteCurrentPage);
    },
    // 分頁顯示元素轉為數字類型
    nlyPgLimit: function() {
      return isNaN(this.toInteger(this.limit))
        ? 5
        : this.toInteger(this.limit) <= 4
        ? 5
        : this.toInteger(this.limit);
    },
    // 計算總頁數
    nlyPgPages: function() {
      return Math.ceil(this.nlyPgTotal / this.nlyPgSize);
    },
    // 生成不包括上一頁,下一頁等按鈕的分頁元素
    nlyPgItemArray: function() {
      if (
        this.nlyPgCurrentPage + 1 <= this.nlyPgLimit &&
        this.nlyPgPages < this.nlyPgLimit
      ) {
        // 當前頁碼+1小于分頁元素且總頁數大于分頁元素
        const itemList = Array.from({ length: this.nlyPgPages }).map(
          (v, k) => k + 1
        );
        return itemList;
      } else if (
        this.nlyPgCurrentPage + 1 <= this.nlyPgLimit &&
        this.nlyPgPages == this.nlyPgLimit
      ) {
        // 當前頁碼+1小于分頁元素且總頁數等于分頁元素
        const itemList = Array.from({ length: this.nlyPgLimit }).map(
          (v, k) => k + 1
        );
        return itemList;
      } else if (
        this.nlyPgCurrentPage + 2 <= this.nlyPgLimit &&
        this.nlyPgPages > this.nlyPgLimit
      ) {
        // 當前頁碼+2小于分頁元素且總頁數大于分頁元素
        const itemList = Array.from({ length: this.nlyPgLimit - 1 }).map(
          (v, k) => k + 1
        );
        itemList.push("···");
        return itemList;
      } else if (
        this.nlyPgPages - this.nlyPgCurrentPage + 2 < this.nlyPgLimit &&
        this.nlyPgPages > this.nlyPgLimit
      ) {
        // 總頁數-當前頁碼+2小于分頁元素且總頁數大于分頁元素
        const itemList = Array.from({ length: this.nlyPgLimit - 1 }).map(
          (v, k) => k + (this.nlyPgPages - this.nlyPgLimit + 2)
        );
        itemList.splice(0, 0, "···");
        return itemList;
      } else if (
        // 總頁數-當前頁碼+2小于分頁元素且總頁數等于分頁元素
        this.nlyPgPages - this.nlyPgCurrentPage + 2 < this.nlyPgLimit &&
        this.nlyPgPages == this.nlyPgLimit
      ) {
        const itemList = Array.from({ length: this.nlyPgLimit - 1 }).map(
          (v, k) => k + (this.nlyPgPages - this.nlyPgLimit + 2)
        );
        return itemList;
      } else {
        // 其他情況
        const itemList = Array.from({ length: this.nlyPgLimit - 2 }).map(
          (v, k) =>
            k + this.nlyPgCurrentPage - Math.ceil(this.nlyPgLimit / 2) + 2
        );
        itemList.splice(0, 0, "···");
        itemList.push("···");
        return itemList;
      }
    },
    // 分頁位置
    alignClass: function() {
      const align = this.align;
      if (align === "center") {
        return "justify-content-center";
      } else if (align === "end" || align === "right") {
        return "justify-content-end";
      }
      return "";
    },
    // 生成包括最后一頁,上一頁,第一頁,下一頁等按鈕的元素,最終分頁元素
    tempalteArray: function() {
      return this._tempalteArray();
    }
  },

4、 頁面渲染created生命周期

  created() {
    // 初始化初始頁面
    this.tempalteCurrentPage = isNaN(this.toInteger(this.currentPage))
      ? 1
      : this.toInteger(this.currentPage) <= 1
      ? 1
      : this.toInteger(this.currentPage);
  },

5、 頁面監控watch

  watch: {
    // 暴露當前頁碼給父組件(變化之前的,如果從第4頁跳轉到第5頁,父組件獲取的值是4)
    tempalteCurrentPage: function() {
      this.$emit("getCurrentPage", this.tempalteCurrentPage);
    },
    // 監測父組件傳入的初始頁碼currentPage,發生變化就給分頁當前頁碼賦值
    currentPage: function(newval, oldval) {
      if (newval != oldval) {
        this.tempalteCurrentPage = this.toInteger(this.currentPage);
      }
    },
    // 監測總頁數,當頁數(即總數量發生變化的時候),如果當前頁碼大于總頁數,當前頁碼變為最大頁面,否則不變,
    nlyPgPages: function(newval, oldval) {
      if (newval != oldval) {
        this.tempalteCurrentPage =
          this.tempalteCurrentPage > newval ? newval : this.tempalteCurrentPage;
      }
    },
    // 監測每頁數量變化,發生變化的時候,重新執行_sizeFunction(),不傳入組件參數sizeFunction也會執行。
    nlyPgSize: function(newval, oldval) {
      if (newval != oldval) {
        this._sizeFunction();
      }
    }
  }

6、 css

<style>
.nly-pagination-item {
  cursor: pointer;
  color: #007bff;
}
</style>

7、 template

<template>
  <ul :class="'pagination ' + alignClass">
    <template v-for="(item, index) in tempalteArray">
      <!-- 跳轉第一頁按鈕 -->
      <template v-if="item == '??'">
        <!-- 當前頁面為第一頁的時候禁用 -->
        <li
          class="page-item disabled"
          :key="index"
          v-if="nlyPgCurrentPage == 1"
        >
          <a class="page-link"> {{ item }}</a>
        </li>
        <!-- 當前頁面不為第一頁的時候 -->
        <li
          class="page-item nly-pagination-item"
          :key="index"
          v-else
          @click="_firstFunction"
        >
          <a class="page-link"> {{ item }}</a>
        </li>
      </template>

      <!-- 上一頁按鈕 -->
      <template v-else-if="item == '?'">
        <!-- 當前頁面為第一頁的時候禁用 -->
        <li
          class="page-item disabled"
          :key="index"
          v-if="nlyPgCurrentPage == 1"
        >
          <a class="page-link"> {{ item }}</a>
        </li>

        <!-- 當前頁面不為第一頁的時候 -->
        <li
          class="page-item nly-pagination-item"
          :key="index"
          v-else
          @click="_prevFunction"
        >
          <a class="page-link"> {{ item }}</a>
        </li>
      </template>

      <!-- 省略按鈕 禁用 -->
      <template v-else-if="item == '···'">
        <li class="page-item disabled" :key="index">
          <a class="page-link"> {{ item }}</a>
        </li>
      </template>

      <!-- 跳轉到最后一頁按鈕 -->
      <template v-else-if="item == '??'">
        <!-- 當前頁面為最后一頁的時候禁用 -->
        <li
          class="page-item disabled"
          :key="index"
          v-if="nlyPgCurrentPage == nlyPgPages"
        >
          <a class="page-link"> {{ item }}</a>
        </li>
        <!-- 當前頁面不為最后一頁的時候 -->
        <li
          class="page-item nly-pagination-item"
          :key="index"
          v-else
          @click="_lastFunction"
        >
          <a class="page-link"> {{ item }}</a>
        </li>
      </template>

      <!-- 下一頁按鈕 -->
      <template v-else-if="item == '?'">
        <!-- 當前頁面為最后一頁的時候禁用 -->
        <li
          class="page-item disabled"
          :key="index"
          v-if="nlyPgCurrentPage == nlyPgPages"
        >
          <a class="page-link"> {{ item }}</a>
        </li>
        <!-- 當前頁面不為最后一頁的時候 -->
        <li
          class="page-item nly-pagination-item"
          :key="index"
          v-else
          @click="_nextFunction"
        >
          <a class="page-link"> {{ item }}</a>
        </li>
      </template>

      <!-- 當前頁碼激活狀態 -->
      <template v-else-if="item == tempalteCurrentPage">
        <li
          class="page-item active nly-pagination-item"
          :key="index"
          @click="_currentFunction(item)"
        >
          <a class="page-link"> {{ item }}</a>
        </li>
      </template>

      <!-- 點擊跳轉頁碼 -->
      <template v-else>
        <li
          class="page-item nly-pagination-item"
          :key="index"
          @click="_currentFunction(item)"
        >
          <a class="page-link"> {{ item }}</a>
        </li>
      </template>
    </template>
  </ul>
</template>

8、 組件

  • 1 新建一個vue項目,過程省略。這里用的vue cli3以上版本。
    目錄如下


    目錄
  • 2 在components下建立一個NLYpagination.vue和index.js


    新建文件

vue文件名字隨意,index最好不改,如果改了在接下來的main.js引入的時候也有改。
把上面的代碼放到NLYpagination.vue中。

  • 注冊組件

打開剛剛建立的index.js,寫入以下代碼。注意import路徑

import NLYpagination from "../components/NLYpagination.vue";

export default {
  install: Vue => {
    Vue.component("NLY-pagination", NLYpagination);
  }
};

在main.js中引入添加以下代碼引入index.js

import pagination from "./components/index.js";
Vue.use(pagination);

完整的main.js應該是這樣

main.js

9、 demo

在需要分頁組件的地方,使用組件就行。

<template>
    <NLY-pagination
      ref="pagination"
      :total="total"
      :size="size"
      :limit="limit"
      align="center"
      :currentPage="currentPage"
      :firstFunction="firstFunction"
      :prevFunction="prevFunction"
      :currentFunction="currentFunction"
      :nextFunction="nextFunction"
      :lastFunction="lastFunction"
      :sizeFunction="sizeFunction"
      @getCurrentPage="getCurrentPage"
    />
</template>
<script>
export default {
  data() {
    return {
      currentPage: 1,
      total: 100,
      size: 10,
      limit: 5
    };
  },
  methods: {
    firstFunction() {
      console.log(
        `跳到第一頁: 從第 ${this.currentPage} 頁跳轉到 ${this.$refs["pagination"].tempalteCurrentPage} 頁`
      );
    },
    prevFunction() {
      console.log(
        `跳到上一頁: 從第 ${this.currentPage} 頁跳轉到 ${this.$refs["pagination"].tempalteCurrentPage} 頁`
      );
    },
    currentFunction() {
      console.log(
        `點擊跳轉到當前點擊頁碼頁面: 從第 ${this.currentPage} 頁跳轉到 ${this.$refs["pagination"].tempalteCurrentPage} 頁`
      );
    },
    nextFunction() {
      console.log(
        `跳到下一頁: 從第 ${this.currentPage} 頁跳轉到 ${this.$refs["pagination"].tempalteCurrentPage} 頁`
      );
    },
    lastFunction() {
      console.log(
        `跳到最后一頁: 從第 ${this.currentPage} 頁跳轉到 ${this.$refs["pagination"].tempalteCurrentPage} 頁`
      );
    },
    sizeFunction() {
      console.log("修改每頁數量");
    },
    getCurrentPage(data) {
      this.currentPage = data;
    },
    getPages(val) {
      console.log(val);
    }
  }
};
</script>
<!--
total: 總數
size: 每頁數量,默認10
currentPage: 初始頁碼
limit: 顯示頁碼個數
align:分頁位置,left左邊,center中間,right右邊,默認左邊
firstFunction: 第一頁按鈕函數
prevFunction: 上一頁按鈕函數
currentFunction: 點擊頁碼函數
nextFunction: 下一頁頁碼函數
lastFunction: 最后一頁頁碼函數
sizeFunction: 修改每頁數量自動執行函數
 -->

演示效果如下:


pg.gif
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Vue 實例 屬性和方法 每個 Vue 實例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,241評論 0 6
  • 本篇文章是一篇Vue.js的教程,目標在于用一種常見的業務場景——分頁/無限加載,幫助讀者更好的理解Vue.js中...
    ElToro閱讀 4,187評論 0 44
  • 主要還是自己看的,所有內容來自官方文檔。 介紹 Vue.js 是什么 Vue (讀音 /vju?/,類似于 vie...
    Leonzai閱讀 3,375評論 0 25
  • 感賞自己堅持讀書,抓緊一切時間聽老師的音頻,勤練基本功,積蓄能量提升自己。 感賞自己在看到孩子晚上又出去時,保持心...
    風景_6b35閱讀 212評論 0 8
  • 半隱于江湖 【二月尋嵩】 第一次聽說許嵩是因為朋友阿...
    二月尋嵩閱讀 264評論 1 3