Bootstrap vue表的动态分页

Posted

技术标签:

【中文标题】Bootstrap vue表的动态分页【英文标题】:Dynamic pagination for Bootstrap vue table 【发布时间】:2022-01-12 19:17:06 【问题描述】:

我需要使用分页动态填充引导 vue 表。 API 每次调用仅返回 10 个对象,并且对于每个后续页面,必须将最后一个对象的 id 作为查询参数传递以获取接下来的 10 条记录。

例如:如果对https://www.example.com/ 的第一次 GET 调用中的最后一个 id 是“10”,那么在单击“第 2 页”时,GET 调用应该是 https://www.example.com/?page_id=10,依此类推,直到api 不返回任何记录。

我曾尝试使用提供程序功能,但 api 不接受页码作为参数,所以这对我没有帮助。

这是我的 b 表和分页的外观:

<template>
    <b-table
          striped
          hover
          :items="reports"
          :fields="fields"
          :current-page="currentPage"
          :per-page="perPage"
          :busy.sync="isBusy"
        ></b-table>

    <b-pagination
          v-model="currentPage"
          :total-rows="totalRows"
          :per-page="perPage"
        ></b-pagination>       
</template>

<script>
      export default 
      name: "tutorials-list",
      data() 
        return 
          reports: [],
          currentReport: null,
          currentIndex: -1,
          title: "",
          fields: [
             key: "id", label: "ID", sortable: true, sortDirection: "desc" ,
             key: "type", label: "Type", sortable: true, class: "text-center" ,
            
              key: "reported by",
              label: "Reported By",
              sortable: true,
              class: "text-center",
            ,
             key: "actions", label: "Actions" ,
          ],
          perPage: 5,
          totalRows: 1,
          currentPage: 1,
          isBusy: false,
          primary_user_id: 1,
          page_id: null
        ;
      ,
      methods: 
        async retrieveReports() 
          this.isBusy = true
          return await ReportsDataService.getAll(this.primary_user_id, this.page_id ? this.page_id : '')
            .then((response) => 
              const result = response.data["votes"];
              this.reports = result.map((report) => (
                id: report.id,
                type: report.report_type,
                "reported by": report.reported_by,
              ));
              this.isBusy = false
              this.totalRows = this.reports.length
              this.page_id = this.reports[this.reports.length-1].id
              console.log();
              return this.reports
            )
            .catch((e) => 
              this.isBusy = false
              console.log(e);
            );
        ,
</script>

我是前端框架的完全新手,因此非常感谢这里的任何帮助,谢谢!

【问题讨论】:

您可以使用 Bootstrap 表签出 github repo,使用动态 rest api 调用的 Bootrap 分页 jebasuthan.github.io/vue_crud_bootstrap 希望对您有所帮助。 【参考方案1】:

您需要在b-table 组件上将per-page 属性设置为0 以禁用本地分页并允许b-pagination 处理数据。

第 1 步:创建一个html 模板

<template>
  <div id="app">
    <div>
      <b-table
        striped
        hover
        :items="listItems"
        :fields="fields"
        :current-page="currentPage"
        :per-page="0">
        <template v-slot:cell(action)="data">
          <b-button size="sm" class="mr-1" @click="edit(data)"> Edit </b-button>
          <b-button size="sm" @click="deleteRecord(data)"> Delete </b-button>
        </template>
      </b-table>
      <b-pagination
        v-model="currentPage"
        :total-rows="totalPages"
        :per-page="recordsPerPage">
      </b-pagination>
    </div>
  </div>
</template>

第 2 步: 添加model 初始化,操作methodwatchercurrentPage

<script>
import  passengerService  from "./services/passengerService";
export default 
  name: "App",
  data() 
    return 
      listItems: [],
      currentPage: 1,
      totalPages: 0,
      recordsPerPage: 10,
      isLoading: false,
      fields: [
        
          key: "_id",
          label: "ID",
          sortable: true,
          sortDirection: "desc",
        ,
        
          key: "name",
          label: "Passenger Name",
          sortable: true,
          class: "text-center",
        ,
        
          key: "airline[0].name",
          label: "Aireline Name",
          sortable: true,
          image: true,
        ,
        
          key: "airline[0].country",
          label: "Country",
          sortable: true,
        ,
        
          key: "action",
          label: "Actions",
        ,
      ],
      params: "",
    ;
  ,
  created() 
    this.loadPassengers();
  ,
  watch: 
    currentPage: 
      handler: function (value) 
        this.params = `page=$value&size=$this.recordsPerPage`;
        this.loadPassengers();
      ,
    ,
  ,
  methods: 
    loadPassengers() 
      this.isLoading = true;
      this.params = `page=$this.currentPage&size=$this.recordsPerPage`;
      passengerService.getListPassengers(this.params).then((response) => 
        if (response.data) 
          this.listItems = response.data;
          this.totalPages = response.totalPassengers;
          this.isLoading = false;
        
      );
    ,
    deleteRecord(data) 
      this.$bvModal
        .msgBoxConfirm("Are you sure wants to delete?", 
          title: "Please Confirm",
          size: "mm",
          buttonSize: "sm",
          okVariant: "danger",
          okTitle: "YES",
          cancelTitle: "NO",
          footerClass: "p-2",
          hideHeaderClose: false,
          centered: true,
        )
        .then((value) => 
          if (value) 
            this.listItems.splice(data.index, 1);
          
        );
    ,
    edit(data) 
      alert(JSON.stringify(data));
    ,
  ,
;
</script>

第三步:services文件夹下创建一个REST API调用

import axios from "axios";

export const passengerService = 
  getListPassengers
;

function getListPassengers(params) 
  return axios
    .get(`https://api.instantwebtools.net/v1/passenger?$params`, )
    .then((response) => Promise.resolve(response.data))
    .catch((error) => Promise.reject(error.response));

DEMO

【讨论】:

谢谢@Jebasuthan!我被卡住的地方是将最后一个 id 作为下一个 api 调用的参数传递。在您的演示而不是/page=2&amp;size=10 中,我希望api 参数为/page_id=5ff33c715dc552cdb770136c(最后一行中“ID”列的值),并且对于每个页面都类似。你认为你能指出我正确的方向吗? TIA! @JayantKumar 您可以从结果项列表this.reports[this.reports.length-1].id 中获取page_id 并可以传递值 从 1->2->3... 移动时有效,但从 2->1 移回时,this.reports[this.reports.length-1].id 将返回第 2 页上的最后一个 ID,而第 1 页将返回由应该在第 3 页上的记录填充。希望示例说明清楚。 @JayantKumar 通常当我们进行分页时,我们习惯于将记录的pagesize 传递给需要显示的记录。但是根据你的情况,当你尝试前进分页时,你应该使用this.reports[this.reports.length-1].id,而当你进行上一个分页时,你应该使用this.reports[0].id @JayantKumar 您也可以添加观察者以正确设置page_id,如下所示,watch: currentPage (newValue, oldValue) if (newValue &lt; oldValue) this.page_id = this.reports[0].id else if (newValue &gt; oldValue) this.page_id = this.reports[this.reports.length-1].id

以上是关于Bootstrap vue表的动态分页的主要内容,如果未能解决你的问题,请参考以下文章

使用 Laravel 分页和 Bootstrap-vue 分页

如何在 vue 3 vite 中使用 sass 扩展?

我无法实现分页。使用 url 参数帮助实现分页(VUETIFY 或 BOOTSTRAP-VUE)

在 bootstrap-vue 中自定义 b 分页

Bootstrap vue 分页样式

分页将值重置为 1 bootstrap-vue