获取 bootstrap vue 分页以使用 REST api

问题描述 投票:0回答:3

尝试让 Bootstrap Vue 使用 REST api,返回一页数据和记录总数(基于 this):

<template>
  </div>
    <b-pagination 
      v-on:change="onPageChange" 
      :total-rows="totalRows" 
      :per-page="perPage" 
      v-model="currentPage"  />
    <b-table responsive striped hover show-empty
      stacked="md"
      :items="items"
      :fields="fields"
      :current-page="currentPage"
      :per-page="perPage"
      :filter="filter"
      :sort-by.sync="sortBy"
      :sort-desc.sync="sortDesc"
      :sort-direction="sortDirection"
      @filtered="onFiltered">
    </b-table>
  </div>
</template>
<script>
...
export default {
  name: 'TableList',
  data() {
    return {
      module: null,
      title: 'Table',
      items: [],
      fields: [],
      errors: [],
      currentPage: 1,
      perPage: 15,
      totalRows: 0,
      pageOptions: [ 5, 10, 15 ],
      sortBy: null,
      sortDesc: false,
      sortDirection: 'asc',
      filter: null,
    }
  },
  created() {
    ...
    this.fetch();
  },
  methods: {
    fetch() {
      var me = this;
      var requestParams = {
        page: this.currentPage,
        per_page: this.perPage
      };
      if(this.sortBy) {
        requestParams = Object.assign({ sort_by: this.sortBy }, requestParams);
      }
      Rest('GET', '/table/' + this.table, requestParams, this.$root.user.token)
      .then(response => {
        me.items = response.data[1]
        me.totalRows = response.data[0].total_entries
      })
      .catch(error => {
        this.errors.push('Error: ' + error.response.status + ': ' + error.response.statusText)
      })
      .finally(() => {
        //alert('turn off loader!');
      });
    }
  }
</script>

如果我获取整个表,这个 Vue 就可以工作。但是,当我使用REST api一次返回一页时,计算出的页数为1,并且前进和结束链接处于非活动状态。因此,我无法触发例如以下请求:第 2 页。

REST api 正确返回表中的总行数以及请求的行数,但 Bootstrap Vue 似乎没有对 this.totalRows 的更改进行观察/反应。

我错过了什么?

vue.js bootstrap-4 bootstrap-vue
3个回答
36
投票

您需要将

per-page
组件上的
b-table
属性设置为 0,以禁用本地分页并允许
b-pagination
处理数据。这是一个例子:

new Vue({
  el: '#app',
  data() {
    return {
      items: [],
      fields: [{
          key: 'postId',
          label: 'Post ID'
        },
        {
          key: 'id',
          label: 'ID'
        },
        {
          key: 'name',
          label: 'Name'
        },
        {
          key: 'email',
          label: 'Email'
        },
        {
          key: 'body',
          label: 'Body'
        }
      ],
      currentPage: 0,
      perPage: 10,
      totalItems: 0
    }
  },
  mounted() {
    this.fetchData().catch(error => {
      console.error(error)
    })
  },
  methods: {
    async fetchData() {
      this.items = await fetch(`https://jsonplaceholder.typicode.com/comments?_page=${this.currentPage}&_limit=${this.perPage}`)
        .then(res => {
          this.totalItems = parseInt(res.headers.get('x-total-count'), 10)

          return res.json()
        })
        .then(items => items)
    }
  },
  watch: {
    currentPage: {
      handler: function(value) {
        this.fetchData().catch(error => {
          console.error(error)
        })
      }
    }
  }
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.22/vue.js"></script>
<script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>

<div id="app">
  <b-table show-empty :items="items" :fields="fields" :current-page="currentPage" :per-page="0"></b-table>
  <b-pagination size="md" :total-rows="totalItems" v-model="currentPage" :per-page="perPage"></b-pagination>
</div>


1
投票

您还可以禁用表格中的本地分页,以便您的项目提供者负责控制分页。


0
投票

我的方法是将 items 提供程序函数注入到 B-Table (

:items="fetchData"
) 的 items 属性中,以便它可以在表状态发生变化时随时运行此函数。

// using TypeScript
{
  methods: {
    public fetchData(
        context: { [key: string]: any },
        callback: (items: Inspection[]) => void
    ): null {
        const params = new URLSearchParams()

        params.append("page", context.currentPage)
        params.append("count", context.perPage)
        params.append("sort", context.sortBy)
        params.append("sort_order", context.sortDesc ? "DESC" : "ASC")

        this.$store
            .dispatch(Actions.FETCH_ITEMS)
            .then(success => success && callback(
                this.$store.state.items ?? []
            ))

        return null
    }
}

在本例中,我使用的是 Vuex,调度程序进行 HTTP 调用,并通过突变将其保存在存储中。因此,之后我只需通过商店访问这些项目并将它们传递给回调函数以触发重新渲染。

传入的上下文对象提供表状态,例如当前页面、显示的行、排序列和顺序,因此您应该可以创建一个可以附加到 API 端点的查询字符串。

如果由于某种原因需要手动触发重新渲染,只需在表上使用 ref 并调用刷新方法即可:

{
  methods: {
    rerender() {
      this.$refs.table.refresh()
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.