如何使用 Vue 实现表格的分页和排序?

1. 简介

Vue.js 是一个用于创建 Web 应用程序的 JavaScript 框架。它可以与现有的 Web 应用程序进行集成,并支持单文件组件、路由、状态管理和构建工具等特性。

在开发 Vue.js 应用程序时,我们通常需要用到表格来展示数据。在涉及到大量数据时,我们会面临展示数据的分页和排序问题,本篇文章将介绍如何使用 Vue 实现表格的分页和排序。

2. 分页实现

2.1 分页插件

在实现分页之前,我们需要选择一个合适的分页插件。市场上有很多分页插件可以选择,比如 vuetable-2vue-pagination-2 等。本文使用 laravel-vue-pagination 插件作为示例。

2.2 分页组件

使用分页插件后,我们需要实现一个分页组件,用于展示分页信息和触发分页事件。

分页组件包含以下属性:

total-pages: 总页数

page-number: 当前页数

on-change: 分页事件的回调函数

分页组件代码如下:

<template>

<nav aria-label="Page navigation">

<ul class="pagination">

<li :class="{ disabled: pageNumber <= 1 }">

<a href="#" @click.prevent="prevPage"><span aria-hidden="true">«</span></a>

</li>

<li :class="{ active: i === pageNumber }" v-for="i in totalPageNumbers">

<a href="#" @click.prevent="changePage(i)">{{ i }}</a>

</li>

<li :class="{ disabled: pageNumber >= totalPages }">

<a href="#" @click.prevent="nextPage"><span aria-hidden="true">»</span></a>

</li>

</ul>

</nav>

</template>

<script>

export default {

name: "Pagination",

props: {

totalPages: {

type: Number,

required: true

},

pageNumber: {

type: Number,

default: 1

},

onChange: {

type: Function,

required: true

}

},

computed: {

totalPageNumbers() {

let pages = [];

for (let i = 1; i <= this.totalPages; i++) {

pages.push(i);

}

return pages;

}

},

methods: {

changePage(pageNumber) {

if (pageNumber !== this.pageNumber) {

this.onChange(pageNumber);

}

},

prevPage() {

if (this.pageNumber > 1) {

this.changePage(this.pageNumber - 1);

}

},

nextPage() {

if (this.pageNumber < this.totalPages) {

this.changePage(this.pageNumber + 1);

}

}

}

};

</script>

2.3 表格组件

实现了分页组件后,我们需要在表格组件中引入分页组件,并使用分页插件提供的 API 完成分页逻辑。

表格组件包含以下属性:

data-api-url: 获取数据的 API 地址

表格组件代码如下:

<template>

<div>

<table class="table">

<thead>

<tr>

<th v-for="(header, key) in headers" :key="key">

{{ header }}

<span class="icon" v-if="sortColumn === key">

<i :class="[sortOrder === 'asc' ? 'fas fa-chevron-up' : 'fas fa-chevron-down']"></i>

</span>

<span class="pull-right">

<i class="fa fa-sort" aria-hidden="true" @click="sortTable(key)"></i>

</span>

</th>

</tr>

</thead>

<tbody>

<tr v-for="(item, index) in pagedData" :key="index">

<td v-for="(field, key) in fields" :key="key">{{ item[field] }}</td>

</tr>

</tbody>

</table>

<pagination

:total-pages="totalPages"

:page-number="currentPage"

:on-change="changePage"

/>

</div>

</template>

<script>

import axios from 'axios';

import Pagination from './Pagination';

export default {

name: "Table",

components: { Pagination },

props: {

dataApiUrl: {

type: String,

required: true

}

},

data() {

return {

data: [],

fields: [],

headers: [],

sortColumn: "",

sortOrder: "",

currentPage: 1,

perPage: 10

};

},

computed: {

totalPages() {

return Math.ceil(this.data.length / this.perPage);

},

pagedData() {

const start = (this.currentPage - 1) * this.perPage;

const end = start + this.perPage;

return this.data.slice(start, end);

}

},

created() {

this.loadData();

},

methods: {

loadData() {

axios.get(this.dataApiUrl).then(response => {

this.data = response.data;

if (this.data.length > 0) {

this.fields = Object.keys(this.data[0]);

this.headers = this.fields.map(field => field.toUpperCase());

}

});

},

changePage(pageNumber) {

this.currentPage = pageNumber;

},

sortTable(column) {

if (this.sortColumn === column) {

this.sortOrder = this.sortOrder === "asc" ? "desc" : "asc";

} else {

this.sortOrder = "asc";

this.sortColumn = column;

}

this.data.sort((a, b) => {

if (this.sortOrder === "asc") {

return a[column].localeCompare(b[column]);

} else {

return b[column].localeCompare(a[column]);

}

});

}

}

};

</script>

2.4 示例

使用上述代码,即可完成表格的分页。下面是一个简单示例。

<template>

<div>

<table-api

data-api-url="/api/users"

/>

</div>

</template>

<script>

import TableApi from './TableApi';

export default {

name: "App",

components: { TableApi }

};

</script>

3. 排序实现

3.1 排序组件

在分页基础上,实现排序也比较简单。我们只需要在表头添加排序按钮,点击后触发排序事件,重新渲染表格即可。

排序组件包含以下属性:

sort-column: 当前排序列

sort-order: 当前排序顺序

on-sort: 排序事件的回调函数

排序组件代码如下:

<template>

<th v-for="(header, key) in headers" :key="key">

{{ header }}

<span class="icon" v-if="sortColumn === key">

<i :class="[sortOrder === 'asc' ? 'fas fa-chevron-up' : 'fas fa-chevron-down']"></i>

</span>

<span class="pull-right">

<i class="fa fa-sort" aria-hidden="true" @click="sortTable(key)"></i>

</span>

</th>

</template>

<script>

export default {

name: "SortableHeader",

props: {

sortColumn: {

type: String,

default: ""

},

sortOrder: {

type: String,

default: ""

},

onSort: {

type: Function,

required: true

},

headers: {

type: Array,

required: true

}

},

methods: {

sortTable(column) {

this.onSort(column);

}

}

};

</script>

3.2 示例

使用上述代码,即可完成表格的排序功能。下面是一个简单示例。

<template>

<div>

<table-api

data-api-url="/api/users"

/>

</div>

</template>

<script>

import TableApi from './TableApi';

export default {

name: "App",

components: { TableApi }

};

</script>

4. 总结

本篇文章介绍了如何使用 Vue.js 实现表格的分页和排序功能:

使用分页插件完成分页逻辑

实现分页组件和表格组件

使用排序组件完成排序功能

VUE数据渲染和分页,排序还是非常容易的,了解下就可以去胜任。