vue3+TS 二次封装Eement-plus 表格+分页组件
由于项目中频繁的使用表格,会出现非常多的重复代码,所以决定对element-plus的table表格、Pagination分页进行二次封装,尽量避免代码冗余。
·
由于项目中频繁的使用表格,会出现非常多的重复代码,所以决定对element-plus的table表格、Pagination分页进行二次封装,尽量避免代码冗余。代码如下:
1、在components文件下新建CommonTable/CommonTable.vue文件
<template>
<div class="table">
<el-table
:data="tableData"
border
style="width: 100%"
max-height="300"
v-loading="loading"
@selection-change="selectionChange"
>
<el-table-column type="selection" width="50" />
<template v-for="(item, index) in tableHeader">
<!-- 插槽:标题文字要特殊显示 | 操作 -->
<el-table-column
v-if="item.slot"
:key="index"
:prop="item.prop"
:label="item.label"
:fixed="item.fixed"
:align="item.align || 'center'"
:show-overflow-tooltip="item.overHidden || false"
:min-width="item.minWidth || '100px'"
:sortable="item.sortable || false"
:type="item.type"
:width="item.width"
>
<slot :name="item.slot"></slot>
</el-table-column>
<!-- 文字不需要特殊显示 -->
<el-table-column
v-else
:key="index + 1"
:prop="item.prop"
:label="item.label"
:fixed="item.fixed"
:align="item.align || 'center'"
:show-overflow-tooltip="item.overHidden || false"
:min-width="item.minWidth || '100px'"
:sortable="item.sortable || false"
:type="item.type"
:width="item.width"
>
<template #default="scope">
<span>{{ scope.row[item.prop] ? scope.row[item.prop] : "" }}</span>
</template>
</el-table-column>
</template>
</el-table>
<!-- 分页 -->
<el-pagination
:locale="locale"
background
class="pagination"
small
:page-sizes="pageSizesArr"
@size-change="sizeChange"
@current-change="currentChange"
:current-page="current"
:page-size="size"
:total="total"
:layout="layout"
/>
</div>
</template>
<script setup lang='ts'>
import { defineProps, defineEmits, onMounted, reactive, ref } from "vue";
const emits = defineEmits(["selectionChange", "sizeChange", "currentChange"]);
const props = defineProps({
// 表格显示的数据
tableData: {
type: String,
// default: function () {
// return [];
// },
},
// 表头数据
tableHeader: {
type: String,
default: function () {
return [];
},
},
// 总页数
total: {
type: Number,
// 类型
required: true,
default: 0,
},
// 分页的页容量数组
pageSizesArr: {
type: Array,
default() {
return [10, 20, 30, 50];
},
},
// 分页的布局
layout: {
type: String,
default: "total, sizes, prev, pager, next, jumper",
},
});
//表格事件
const selectionChange = (val) => {
emits("selectionChange", val);
};
// 页数改变的时候触发的事件
const sizeChange = (val) => {
emits("sizeChange", val);
};
// 当前页改变的时候触发的事件
const currentChange = (val) => {
emits("currentChange", val);
};
</script>
<style lang="less" scoped>
.table {
margin-top: 1rem;
}
.pagination {
float: right;
margin-top: 1.25rem;
margin-bottom: 1.25rem;
}
</style>
2、组件中使用
<template>
<el-card class="main-card">
<!-- 表格展示 -->
<CommonTable
:tableData="tableData"
:tableHeader="tableHeader"
:isOperate="isOperate"
:total="total"
:operateWidth="operateWidth"
@handleSizeChange="sizeChange"
@handleCurrentChange="currentChange"
>
<template v-slot:isReview>
<el-tag v-if="isReview == 0" type="warning">审核中</el-tag>
<el-tag v-if="isReview == 1" type="success">正常</el-tag>
</template>
<template v-slot:state>
<el-tag v-if="state == 1">文章</el-tag>
<el-tag v-if="state == 2" type="danger">留言</el-tag>
<el-tag v-if="state == 3" type="success">关于我</el-tag>
<el-tag v-if="state == 4" type="warning">友链</el-tag>
<el-tag v-if="state == 5" type="warning">说说</el-tag>
</template>
<template v-slot:action>
<el-button
v-if="action == 0"
size="mini"
type="success"
@click="updateCommentReview(scope.row.id)">
通过
</el-button>
<el-popconfirm style="margin-left: 10px" title="确定删除吗?" @confirm="deleteComments(scope.row.id)">
<el-button size="mini" type="danger"> 删除 </el-button>
</el-popconfirm>
</template>
</CommonTable>
</el-card>
</template>
<script setup lang='ts'>
import { reactive, ref, onMounted, computed } from "vue-demi";
import CommonTable from "../../components/Table/CommonTable.vue";
// import { defineStore } from "pinia";
// const store = defineStore();
// 表格所需的数据
const tableData = reactive([
{
avatar: "头像",
nickname: "评论人",
replyNickname: "回复人",
articleTitle: "文章标题",
commentContent: "评论内容",
createTime: "评论时间",
isReview: "状态",
},
]);
//表头数据 辅助tableData的数据 tableData是自己定义
const tableHeader = reactive([
{
prop: "avatar",
fixed: "left",
label: "头像",
width: "130px",
align: "center", // 对齐方式
},
{
prop: "nickname",
label: "评论人",
width: "130px",
align: "center", // 对齐方式
},
{
prop: "replyNickname",
label: "回复人",
width: "130px",
align: "left", // 对齐方式
},
{
prop: "articleTitle",
label: "文章标题",
width: "130px",
align: "left", // 对齐方式
},
{
prop: "commentContent",
label: "评论内容",
width: "130px",
align: "left", // 对齐方式
},
{
prop: "createTime",
label: "评论时间",
width: "130px",
align: "left", // 对齐方式
},
{
prop: "isReview", //prop
label: "状态", //label
slot: "isReview", //插槽根据需求显示
width: "130px", //宽度
align: "left", // 对齐方式
fixed:''//固定左侧或右侧?true/flase
},
{
label: "来源",
slot: "state",
width: "130px",
align: "left", // 对齐方式
},
{
label: "操作",
slot: "action",
fixed: "right",
width: "130px",
align: "center", // 对齐方式
},
]);
const operateWidth = ref(160); // 操作列宽度
const isOperate = ref(true); // 操作列是否显示
const pageSize = ref(10); // 每页显示条数
const pageNum = ref(2); // 当前页码
const total = ref(100); // 总条数
const isReview=ref(0);
const state=ref(1);
const action=ref(0)
// const isReview=ref(null);
// 分页改变事件
const sizeChange = (val) => {
pageSize.value = val;
};
// 当前页改变事件
const currentChange = (val) => {
pageNum.value = val;
};
</script>
<style lang="less" scoped>
.article-status-menu {
font-size: 14px;
margin-top: 16px;
color: #999;
}
.table {
margin-top: 10px;
.option-box {
margin-top: 1.5rem;
.el-select {
margin-right: 1.5rem;
}
.search {
margin-top: 0.5rem;
}
}
.operation-container {
display: flex;
align-items: center;
// margin-bottom: 1.25rem;
// margin-top: 1.25rem;
}
}
.el-table {
margin-top: 1rem;
}
</style>
3、效果图
更多推荐
已为社区贡献1条内容
所有评论(0)