Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主
**🐱🐉🐱🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求收藏,求评论,求一个大大的赞!👍**
已经有很久没有写文章了,贪玩,摆烂,不想动,低情绪。
下半年遇到的不如意的事情太多了,极为烦躁,陷入迷茫,所幸现在清醒一些了。
之前的封装组件的时候,就在意,什么是好的组件封装?
总想着把事情做的全面一点,可是自己有不具备那样的实力,到头来还是要回归的项目需求的本身上来
“满足实际需求就是好的”
至于可扩展,兼容的问题实在是不能在每个需求来到是都一一考虑,现在我的水平也不够
所以必须谨记“满足实际需求就是好的”
此文为 Vue3 + ElementPlus 封装 通用表格组件的记录,以便后用
- 最终源码在最后
- 本文仅为 封装组件的 源码
- 如何使用 不在此文 之内,见资源(包含使用示例+组件源码)
vue3-ElmentPlus封装通用表格源码
vue3-ElmentPlus封装通用表格
文章目录
- vue3-ElmentPlus封装通用表格
- 效果
- 通用功能包含
- 实现过程
- 表头、表格数据渲染 (标准组件源码:`myTable.vue`)
- 单元格操作(如:详情、修改,删除等位于 单元格最后)
- 多选
- 分页器
- 内容局中
- 最终源码:
- 🦖我是Sam9029,一个前端
效果
通用功能包含
- 表头、表格数据渲染(将表头、表格数据单独抽离出来)
- 单元格操作(如:详情、修改,删除等位于 单元格最后)
- 多选
- 分页器
- 内容居中
实现过程
- 表头、表格数据渲染 的是标准模板 组件
- 依次往里面 进行 修改
表头、表格数据渲染 (标准组件源码:myTable.vue
)
- 将表头单独提取出来
- 接收 表格数据 控制渲染
- tableData 控制表格内容数据
- tableController 控制表格表头数据
- 注意 表格数据与表头数据的对应关系
// 表格内容数据
let tableData = {
title1:`content`,
title2:`content`,
}
// 表格表头数据
let tableController:[
{key: 'title1', value: 'title1'},
{key: 'title2', value: 'title2'},
// type: 'template' 用于识别该列 是否 为操作列
{key: '操作', value: 'opt', type: 'template', width: '180'}
]
- 封装组件(
myTable.vue
)实现如下:
<template>
<!-- 此处 可以 拓展 (elplus table 的特殊 表格props属性 ) -->
<!-- :data="tableData" 绑定表格数据 -->
<el-table :data="tableData" border style="width: 100%">
<!-- 接受 传值 渲染 表头 -->
<!-- 表头数据的 单独控制tableController -->
<!-- 可控制宽度 -->
<el-table-column
v-for="t in tableController"
:label="t.key"
:prop="t.value"
:width="t.width ? t.width : ''"
>
</el-table>
</template>
<script setup>
// 接收 所有 props 传值
const props = defineProps({
// 表格数据
tableData: {
type: Array,
default: []
},
// 表头数据
tableController: {
type: Array,
default: []
},
})
</script>
单元格操作(如:详情、修改,删除等位于 单元格最后)
- 预留插槽 使用表头数据中 type: ‘template’ 用于识别该列 是否 为操作列
- (替换上面 (标准组件源码:
myTable.vue
) 的 )
<el-table-column
v-for="t in tableController"
:prop="t.value"
:label="t.key"
:width="t.width ? t.width : ''"
>
<!-- 预留插槽 (可选)-->
<!-- #default="scope" 作用域插槽 使用子组件内部数据 -->
<template #default="scope" v-if="t.type === 'template'">
<slot :name="t.value" :row="scope.row"></slot>
</template>
</el-table-column>
多选
- 需要的
type="selection"
控制 - 在(标准组件源码:
myTable.vue
) 标签中新增 如下
<!-- 多选(可选) -->
<el-table-column type="selection" width="50" v-if="selected"/>
- JS中新增 接受值
const props = defineProps({
// 是否加载多选
selected: {
type: Boolean,
default: true
}
})
分页器
- 需要 引入 el-pagination
- 盒 同级别引入
<!-- 分页器 (可选) -->
<div v-if="pager">
<el-pagination
v-model:current-page="queryParams.pageNum"
v-model:page-size="queryParams.pageSize"
background
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
- JS中新增
const props = defineProps({
// 是否加载分页器
pager: {
type: Boolean,
default: true
},
})
// 分页器 默认数据
let queryParams = ref({pageNum: 1, pageSize: 10})
// 分页器处理函数
// 单页数据条数改变
function handleSizeChange(ev) {
queryParams.value.pageSize = ev;
emit('pagerFresh', JSON.parse(JSON.stringify(queryParams.value)))
}
// 页数改变
function handleCurrentChange(ev) {
queryParams.value.pageNum = ev;
emit('pagerFresh', JSON.parse(JSON.stringify(queryParams.value)))
}
内容局中
- 在 所有的 的中加入
:align="center?'center':''"
<el-table-column :align="center?'center':''"/>
最终源码:
<template>
<!--
此处 可以 拓展 (elplus table 的特殊 表格props属性 )
比如:树状表格、内容居中、表尾内容、固定行列等
:header-cell-style="{'text-align':`${true}?'center':'auto'`}"
:cell-style="{'text-align':`${true}?'center':'auto'`}"
-->
<!-- :data="tableData" 绑定表格数据 -->
<el-table
:data="tableData"
border
style="width: 100%"
>
<!-- 多选(可选) -->
<el-table-column :align="center?'center':''" type="selection" width="50" v-if="selected"/>
<!-- 序号(应该可选才对-目前没有) -->
<el-table-column :align="center?'center':''" type="index" label="序号" width="55"/>
<!-- 接受 传值 渲染 表头 -->
<!-- 表头数据的 单独控制tableController -->
<!-- 可控制宽度 -->
<el-table-column :align="center?'center':''"
v-for="t in tableController"
:prop="t.value"
:label="t.key"
:width="t.width ? t.width : ''"
>
<!-- 预留插槽 (可选)-->
<!-- #default="scope" 作用域插槽 使用子组件内部数据 -->
<template #default="scope" v-if="t.type === 'template'">
<slot :name="t.value" :row="scope.row"></slot>
</template>
</el-table-column>
</el-table>
<!-- 分页器 (可选) -->
<div class="pager-box" v-if="pager">
<el-pagination
v-model:current-page="queryParams.pageNum"
v-model:page-size="queryParams.pageSize"
background
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</template>
<script setup>
import {ref} from "vue";
// 接收 分页器的分页操作处理函数
const emit = defineEmits(['pagerFresh'])
// 接收 所有 props 传值
const props = defineProps({
// 表格数据
tableData: {
type: Array,
default: []
},
// 表头数据
tableController: {
type: Array,
default: []
},
// 分页所属--总数据条数
total: {
type: Number,
default: 10
},
// 是否加载分页器
pager: {
type: Boolean,
default: true
},
// 是否加载多选
selected: {
type: Boolean,
default: true
},
// 内容居中
center: {
type: Boolean,
default: true
},
})
// 分页器 默认数据
let queryParams = ref({pageNum: 1, pageSize: 10})
// 分页器处理函数
// 单页数据条数改变
function handleSizeChange(ev) {
queryParams.value.pageSize = ev;
emit('pagerFresh', JSON.parse(JSON.stringify(queryParams.value)))
}
// 页数改变
function handleCurrentChange(ev) {
queryParams.value.pageNum = ev;
emit('pagerFresh', JSON.parse(JSON.stringify(queryParams.value)))
}
</script>
<style lang="scss" scoped>
// 内容居中
.text-center{
text-align:center;
}
// 分页器位置
.pager-box {
display: flex;
justify-content: flex-end;
margin-top: 50px;
}
</style>
🦖我是Sam9029,一个前端
文章若有错误,敬请指正🙏
**🐱🐉🐱🐉恭喜你,都看到这了,求收藏,求评论,求一个大大的赞👍!不过分吧**
Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主