Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主

**🐱‍🐉🐱‍🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求收藏,求评论,求一个大大的赞!👍**


已经有很久没有写文章了,贪玩,摆烂,不想动,低情绪。

下半年遇到的不如意的事情太多了,极为烦躁,陷入迷茫,所幸现在清醒一些了。

之前的封装组件的时候,就在意,什么是好的组件封装?

总想着把事情做的全面一点,可是自己有不具备那样的实力,到头来还是要回归的项目需求的本身上来

“满足实际需求就是好的”

至于可扩展,兼容的问题实在是不能在每个需求来到是都一一考虑,现在我的水平也不够

所以必须谨记“满足实际需求就是好的”

此文为 Vue3 + ElementPlus 封装 通用表格组件的记录,以便后用

  • 最终源码在最后
  • 本文仅为 封装组件的 源码
  • 如何使用 不在此文 之内,见资源(包含使用示例+组件源码)

vue3-ElmentPlus封装通用表格源码


vue3-ElmentPlus封装通用表格

效果

请添加图片描述

通用功能包含

  • 表头、表格数据渲染(将表头、表格数据单独抽离出来)
  • 单元格操作(如:详情、修改,删除等位于 单元格最后)
  • 多选
  • 分页器
  • 内容居中

实现过程

  • 表头、表格数据渲染 的是标准模板 组件
  • 依次往里面 进行 修改

表头、表格数据渲染 (标准组件源码: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领域博主

Logo

前往低代码交流专区

更多推荐