Vue.js 中使用 Element UI 实现异步加载分页列表
在前端开发中,我们常常需要展示大量数据,并提供分页浏览的功能。本篇博客将介绍如何使用 Vue.js 和 Element UI 组件库创建一个简单的异步加载分页列表。
技术栈
- Vue.js
- Element UI
- JavaScript
组件结构
我们将创建一个包含表格和分页组件的 Vue 单文件组件。以下是组件的基本结构:
<template><div class="table-container"><!-- 表格组件 --><el-table :data="currentPageData" style="width: 66%"><el-table-column label="ID" prop="id"></el-table-column><el-table-column label="名称" prop="name"></el-table-column><el-table-column label="价格" prop="price"></el-table-column></el-table><!-- 分页组件 --><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage":page-sizes="[10, 20, 30, 40]":page-size="pageSize"layout="total, sizes, prev, pager, next, jumper":total="tableData.length"></el-pagination></div>
</template><script>
export default {data() {return {tableData: [], // 存储列表数据currentPage: 1, // 当前页码pageSize: 10, // 每页条数};},computed: {currentPageData() {// 根据当前页码和每页条数计算当前显示数据const start = (this.currentPage - 1) * this.pageSize;const end = start + this.pageSize;return this.tableData.slice(start, end);},},methods: {handleSizeChange(val) {// 处理每页条数变化this.pageSize = val;this.currentPage = 1; // 将当前页重置为第一页},handleCurrentChange(val) {// 处理当前页变化this.currentPage = val;},},created() {// 模拟异步加载数据setTimeout(() => {this.tableData = Array.from({ length: 33 }, (_, index) => ({id: index + 1,name: `商品${index + 1}`,price: Math.floor(Math.random() * 100) + 50,}));}, 500);},
};
</script><style scoped>
.table-container {display: flex;justify-content: center;align-items: center;flex-direction: column;
}
</style>
创建过程
-
引入 Element UI: 在项目中引入 Element UI 组件库。可以使用 npm 或 yarn 安装 Element UI。
npm install element-ui
在
main.js
中引入并使用 Element UI:import Vue from 'vue'; import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css';Vue.use(ElementUI);
-
创建组件: 创建一个 Vue 单文件组件,定义表格和分页的结构。
-
异步加载数据: 使用
created
钩子模拟异步加载数据。在实际项目中,将从后端 API 获取数据。 -
分页功能: 使用 Element UI 提供的分页组件实现分页功能。监听分页组件的事件,更新当前页码和每页条数。
main.js :
import Vue from 'vue'import App from './App.vue'import ElementUI from 'element-ui';import 'element-ui/lib/theme-chalk/index.css';import ListDisplay from './components/ListDisplay.vue';Vue.config.productionTip = falseVue.use(ElementUI);new Vue({render: h => h(App),components: {ListDisplay,},template: '<ListDisplay />',}).$mount('#app')
App.vue:
<template><div id="app"><ListDisplay /></div>
</template><script>
import ListDisplay from "@/components/ListDisplay.vue";
// import ListDisplay from "@/components/separation-of-duties/ListDisplay.vue";export default {name: 'App',components: {ListDisplay,}
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;color: #2c3e50;margin-top: 60px;
}
</style>
当然列表组件也可以拆开来展示
<template><div class="table-container"><MyTable :data="currentPageData"></MyTable><MyPagination:current-page="currentPage":page-size="pageSize":total="tableData.length"@size-change="handleSizeChange"@current-change="handleCurrentChange"></MyPagination></div>
</template><script>
import MyTable from "././MyTable.vue";
import MyPagination from "././MyPagination.vue";export default {components: {MyTable,MyPagination,},data() {return {tableData: [],currentPage: 1,pageSize: 10,};},computed: {currentPageData() {const start = (this.currentPage - 1) * this.pageSize;const end = start + this.pageSize;return this.tableData.slice(start, end);},},methods: {handleSizeChange(val) {this.pageSize = val;this.currentPage = 1;},handleCurrentChange(val) {this.currentPage = val;},},created() {// 模拟异步加载数据setTimeout(() => {this.tableData = Array.from({length: 33}, (_, index) => ({id: index + 1,name: `商品${index + 1}`,price: Math.floor(Math.random() * 100) + 50,}));}, 500);},
};
</script><style scoped>
.table-container {display: flex;justify-content: center;align-items: center;flex-direction: column;
}
</style>
MyTable:
<template><el-table :data="data" style="width: 100%"><el-table-column label="ID" prop="id"></el-table-column><el-table-column label="名称" prop="name"></el-table-column><el-table-column label="价格" prop="price"></el-table-column></el-table>
</template><script>
export default {props: {data: {type: Array,default: () => [],},},
};
</script><style scoped>
</style>
MyPagination:
<template><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="currentPage":page-size="pageSize":page-sizes="[10, 20, 30, 40]"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination>
</template><script>
export default {props: {currentPage: {type: Number,required: true,},pageSize: {type: Number,required: true,},total: {type: Number,required: true,},},methods: {handleSizeChange(val) {this.$emit('size-change', val);},handleCurrentChange(val) {this.$emit('current-change', val);},},
};
</script><style scoped>
</style>
实现效果: