技术栈
框架 | 说明 | 版本 |
---|---|---|
Vue | 渐进式 JavaScript 框架 | 3.3.4 |
Vite | 前端开发与构建工具 | 4.4.11 |
Element Plus | 基于 Vue 3,面向设计师和开发者的组件库 | 2.4.1 |
Pinia | 符合直觉的 Vue.js 状态管理库 | 2.1.7 |
vue-router | Vue.js 的官方路由管理库 | 4.2.5 |
Sass | CSS 预处理器 | 1.69.5 |
VueUse | 基于 Vue 组合式 API 的实用工具集 | 10.5.0 |
Axios | 用于浏览器和 Node.js 的基于 Promise 的 HTTP 请求库 | 1.6.0 |
UnoCSS | 原子化CSS引擎 | 0.57.2 |
Eslint | 可配置的 JavaScript 检查器 | 8.52.0 |
写在前面
最近手上有个项目,刚开始开发,在开发一些列表的时候,必须会用到一些分页组件(el-pagination),用过的同学都知道,这个组件的配置参数还是比较多的,所以犹豫了一秒钟,打算自己对它进行一个二次封装
开始
在项目的 components 目录下新建一个 Pagination 文件夹,文件夹中新建一个 index.vue 文件,这里就编写组件的源代码
<script setup>
/**
* 二次封装 el-pagination 组件,组件参数同原组件保持一致
* 官方文档 https://element-plus.org/zh-CN/component/pagination.html
* 抛出 change 事件,触发列表更新
*/
defineOptions({
name: "Pagination",
});
defineProps({
currentPage: {
type: Number,
default: 1,
},
pageSize: {
type: Number,
default: 10,
},
pageSizes: {
type: Array,
default: () => [10, 20, 50, 100],
},
layout: {
type: String,
default: "total, sizes, prev, pager, next, jumper",
},
});
const emits = defineEmits(["update:currentPage", "update:pageSize", "change"]);
/**
* page-size 每页显示条目个数改变时触发
* @param pageSize {Number} 每页显示条目个数
*/
function sizeChange(pageSize) {
emits("update:pageSize", pageSize);
}
/**
* current-page 当前页数改变时触发
* @param currentPage {Number} 当前页数
*/
function currentChange(currentPage) {
emits("update:currentPage", currentPage);
}
/**
* current-page 或 page-size 更改时触发
*/
function change() {
emits("change");
}
</script>
<template>
<el-pagination
class="pagination"
:layout="layout"
:current-page="currentPage"
:page-size="pageSize"
:page-sizes="pageSizes"
v-bind="$attrs"
@change="change"
@size-change="sizeChange"
@current-change="currentChange"
/>
</template>
<style scoped lang="scss">
.pagination {
display: flex;
justify-content: flex-end;
align-items: center;
margin-top: 20px;
}
</style>
这的代码量不是很多,也才七十几行,这里使用了一个 v-bind="$attrs"
这样的一个属性,它可以把外面 props
直接传递到 el-pagination
组件中
组件的使用
<script setup>
import { Search } from "@element-plus/icons-vue";
const params = ref({
name: "",
pageNum: 1,
pageSize: 10,
});
const deviceTotal = ref(288);
const deviceList = ref([
{
id: 1,
name: "设备1",
},
{
id: 2,
name: "设备2",
},
{
id: 3,
name: "设备3",
},
]);
/**
* 获取设备列表
*/
function getDeviceList() {
console.log("获取设备列表", toRaw(params.value));
}
</script>
<template>
<div class="app-container">
<el-form ref="filterForm" class="form-filter" inline :model="params" @submit.prevent>
<el-form-item label="设备名称" prop="name">
<el-input
v-model="params.name"
style="width: 200px"
placeholder="请输入设备名称"
clearable
@keyup.enter="getDeviceList"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="getDeviceList">查 询</el-button>
</el-form-item>
</el-form>
<el-table stripe :data="deviceList">
<el-table-column type="selection" width="55" />
<el-table-column label="设备名称" prop="name" />
</el-table>
<pagination
v-model:current-page="params.pageNum"
v-model:page-size="params.pageSize"
:total="deviceTotal"
@change="getDeviceList"
/>
</div>
</template>
Tips:项目中配置了 unplugin-vue-components
插件自动导入组件,所以在上面没有显示的导入,这个请注意
使用的效果和原来的组件基本一致,这里还可以直接使用官方文档中的属性
使用 v-bind="$attrs"
可以大大减少组件二次封装带来的参数传递困扰,也可以在组件中使用 defineProps
配置来定义默认值
结束
好了,这期分享就到此结束,有更好的推荐,欢迎大家在评论区讨论