Vue2+ElementUI列表、表格组件的封装

Vue2+ElementUI列表组件的封装:引言

在日常开发中,我们经常会遇到需要展示列表数据的场景。ElementUI 提供的 el-table 组件是一个功能强大的表格组件,可以满足大部分的需求。但是,在实际应用中,我们往往需要根据业务需求对 el-table 组件进行二次封装,以提高开发效率和代码的复用性。

本文将介绍 Vue2+ElementUI 列表组件的封装方法,包括:

  • 封装思路
  • 常见功能的实现
  • 代码示例
  • 注意点

封装思路
封装 el-table 组件的思路是将其作为一个独立的组件,对外暴露必要的属性和方法,并通过插槽机制来定制表格的内容。

具体来说,我们可以将 el-table 组件的封装分为以下几个步骤:

  1. 定义组件的 props,用于接收外部传入的数据和配置。
  2. 在组件内部,使用 el-table 组件来渲染表格。
  3. 通过插槽机制来定制表格的内容,例如表头、表尾、操作列等。
  4. 暴露一些方法,用于控制表格的操作,例如刷新、排序、筛选等。

创建组件模板并测试使用

创建组件,名为:H3yunTableCompV1,这是子组件

<template><div><el-tableref="multipleTable"tooltip-effect="dark"style="width: 100%"><el-table-columntype="index"></el-table-column></el-table></div>
</template><script>
export default {name: "H3yunTableCompV1",data() {return {}},methods: {}
}
</script><style scoped></style>

创建测试类并使用上面的组件,方便测试。注意:导入组件时注意路径。这是父组件。

<template><div class="container" style="min-height: 100%; padding-bottom: 100px;"><H3yunTableCompV1></H3yunTableCompV1></div>
</template><script>
import H3yunTableCompV1 from "../../components/table/H3yunTableCompV1";export default {props: [],components: {H3yunTableCompV1},data() {return {}},watch: {},computed: {},beforeCreate() {},created() {},beforeMount() {},mounted() {},beforeUpdate() {},updated() {},destroyed() {},methods: {},
}
</script><style scoped>.container {
}
</style>

父、子组件传值

父组件编写表格对象并传递给子组件。

<H3yunTableCompV1 :data="tableObj"></H3yunTableCompV1>data() {return {// 这个对象可以从后端获取,下面是一些示例数据tableObj: {// 数据列 - 即el-table-column组件中的属性columns: [{prop: 'date', label: '日期', width: '180'},{prop: 'name', label: '名字', width: '180'},{prop: 'address', label: '地址', width: '180'}]}}}

子组件接收值并处理

export default {name: "H3yunTableCompV1",data() {return {// 表格对象   -- 1tableObj: {columns: []}}},// 接收父组件传递过来的值props: {// 接收父组件传递过来的data数据,类型为Object   -- 2data: Object},watch: {// 监控父组件中的data,保证子组件中的tableObj与父组件一致   -- 3data: {deep: true, // 深度监控immediate: true, // 在组件创建时立即触发handler(newVal, oldVal) {this.init(newVal) // 初始化}}},methods: {// 初始化方法   -- 4init(newVal) {for (const key in newVal) {// 如果父组件传的值能与tableObj的属性匹配,比如父子组件都有tableObj.columns,则会进入这个ifif (Object.keys(this.tableObj).includes(key)) {// 比如:tableObj.columns = newVal.columnsthis.tableObj[key] = newVal[key]}}}}
}

子组件循环 columns

<el-tableref="multipleTable"tooltip-effect="dark"style="width: 100%"><el-table-columntype="index"></el-table-column><el-table-columnv-for="(column,key) in tableObj.columns":key="key":prop="column.prop":label="column.label":width="column.width"></el-table-column></el-table>

效果如下

在这里插入图片描述

列隐藏

比如说我想隐藏ID列。我给id这个配置添加一个属性为hide:true

tableObj: {// 数据列 - 即el-table-column组件中的属性columns: [{prop: 'id', label: 'ID', width: '80', hide: true},{prop: 'date', label: '日期', width: '180'},{prop: 'name', label: '名字', width: '180'},{prop: 'address', label: '地址', width: '180'}]}

id列未隐藏之前的效果。
在这里插入图片描述
子组件的el-table-column循环时加个属性v-if="!column.hide"。注意:这里使用v-show的话是不起作用的。

     <el-table-columnv-for="(column,key) in tableObj.columns":key="key":prop="column.prop":label="column.label":width="column.width"v-if="!column.hide"></el-table-column>

隐藏后的效果
在这里插入图片描述

插槽 - 文字链接

先看效果,标题列是通过插槽的方式插入的。

在这里插入图片描述

子组件使用v-if去判断是否是插槽去做分别处理。下面是完整的代码,里面使用了临时数据,后面会通过父组件传递。

<template><div><el-tableref="multipleTable"tooltip-effect="dark"style="width: 100%":data="tableData"@selection-change="handleSelectionChange"><!--多选--><el-table-columntype="selection"width="55"></el-table-column><!--序号--><el-table-columntype="index"></el-table-column><!--插槽处理--><template v-for="(column,key) in tableObj.columns"><el-table-column:key="key":prop="column.prop":label="column.label":width="column.width"v-if="column.type == 'slot'"><template slot-scope="scope"><slot :name="column.slot_name" :row="scope.row"></slot></template></el-table-column><el-table-column:key="key":prop="column.prop":label="column.label":width="column.width"v-else-if="!column.hide"></el-table-column></template></el-table></div>
</template><script>
export default {name: "H3yunTableCompV1",data() {return {// 表格对象   -- 1tableObj: {columns: []},tableData: [{id: 1,title: '标题1',date: '2016-05-02',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄',tag: '家'}, {id: 2,title: '标题2',date: '2016-05-04',name: '王小虎',address: '上海市普陀区金沙江路 1517 弄',tag: '公司'}, {id: 3,title: '标题3',date: '2016-05-01',name: '王小虎',address: '上海市普陀区金沙江路 1519 弄',tag: '家'}]}},// 接收父组件传递过来的值props: {// 接收父组件传递过来的data数据,类型为Object   -- 2data: Object},watch: {// 监控父组件中的data,保证子组件中的tableObj与父组件一致   -- 3data: {deep: true, // 深度监控immediate: true, // 在组件创建时立即触发handler(newVal, oldVal) {this.init(newVal) // 初始化}}},methods: {handleSelectionChange(val) {this.multipleSelection = val;},// 初始化方法   -- 4init(newVal) {for (const key in newVal) {// 如果父组件传的值能与tableObj的属性匹配,比如父子组件都有tableObj.columns,则会进入这个ifif (Object.keys(this.tableObj).includes(key)) {// 比如:tableObj.columns = newVal.columnsthis.tableObj[key] = newVal[key]}}}}
}
</script><style scoped></style>

父组件使用templatev-slot:插槽名去处理插槽。这里是拿到了整行数据而不仅仅是title这一列,里面的内容完全是自定义的。

<H3yunTableCompV1 :data="tableObj">// 处理标题插槽<template v-slot:title_slot="scope"><el-link type="primary">{{ scope.row.title }}</el-link></template>
</H3yunTableCompV1>export default {
components: {H3yunTableCompV1},data() {return {// 这个对象可以从后端获取,下面是一些示例数据tableObj: {// 数据列 - 即el-table-column组件中的属性columns: [{prop: 'title', label: '标题', width: '180', type: 'slot', slot_name: 'title_slot'}, // 定义标题列是插槽{prop: 'date', label: '日期', width: '180'},{prop: 'name', label: '名字', width: '180'},{prop: 'address', label: '地址', width: '180'}]}}}
}

插槽 - 按钮

注意:插槽 - 按钮这个示例是在上一个示例的基础上的。

效果如下:

在这里插入图片描述

增加列,并定义插槽的名称为operate_slot

{prop: 'operate', label: '操作', width: '180', type: 'slot', slot_name: 'operate_slot'}

在这里插入图片描述插槽处理

    <H3yunTableCompV1 :data="tableObj">// 标题 - 插槽<template v-slot:title_slot="scope"><el-link type="primary">{{ scope.row.title }}</el-link></template>// 操作 - 插槽<template v-slot:operate_slot="scope"><el-button-group><el-button type="primary" disabled>编辑</el-button><el-button type="primary" disabled>删除</el-button></el-button-group></template></H3yunTableCompV1>

分页

效果如下:在这里插入图片描述
代码改动比较多,下面直接上代码。

父组件如下,主要增加与后端联动。

<template><div class="container" style="min-height: 100%; padding-bottom: 100px;"><H3yunTableCompV1 :data="tableObj">// 标题 - 插槽<template v-slot:fnsku_slot="scope"><el-link type="primary">{{ scope.row.fnsku }}</el-link></template>// 操作 - 插槽<template v-slot:operate_slot="scope"><el-button-group><el-button type="primary" disabled>编辑</el-button><el-button type="primary" disabled>删除</el-button></el-button-group></template></H3yunTableCompV1></div>
</template><script>
import H3yunTableCompV1 from "../../components/table/H3yunTableCompV1";export default {props: [],components: {H3yunTableCompV1},data() {return {// 这个对象可以从后端获取,下面是一些示例数据tableObj: {http: {// 这个url你们需要写成完整的urlurl: '/logisticSalesPrediction/list',params: {},// url返回结果的数据结构,result: {// 表格内容表示是在result.records中获取list: 'records',// 数据量总数是在result.total中获取total: 'total'}},pageNum: 1,pageSize: 10,total: 0,// 数据列 - 即el-table-column组件中的属性columns: [{prop: 'fnsku', label: 'fnsku', width: '180', type: 'slot', slot_name: 'fnsku_slot'}, // 定义标题列是插槽{prop: 'isSeason', label: '是否是时令性产品', width: '180'},{prop: 'activityIncrement', label: '活动增量', width: '180'},{prop: 'prediction', label: '销量预测', width: '180'},]}}},methods: {},
}
</script><style scoped>.container {
}
</style>

下面是子组件的代码。

首先,在table标签下面增加了分页组件,其次增加了axios的请求,与响应结果的处理。细节部分呢,就是切换页码,页大小和序号。

<template><div><el-tableref="multipleTable"tooltip-effect="dark"style="width: 100%":data="tableData"@selection-change="handleSelectionChange"><!--多选--><el-table-columntype="selection"width="55"></el-table-column><!--序号--><el-table-columntype="index":index="calIndex"></el-table-column><!--插槽处理--><template v-for="(column,key) in tableObj.columns"><el-table-column:key="key":prop="column.prop":label="column.label":width="column.width"v-if="column.type == 'slot'"><template slot-scope="scope"><slot :name="column.slot_name" :row="scope.row"></slot></template></el-table-column><el-table-column:key="key":prop="column.prop":label="column.label":width="column.width"v-else-if="!column.hide"></el-table-column></template></el-table><div><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="tableObj.pageNum":page-sizes="[10, 20, 50, 100]":page-size="tableObj.pageSize"layout="total, sizes, prev, pager, next, jumper":total="tableObj.total"></el-pagination></div></div>
</template><script>import request from "../../utils/request";export default {name: "H3yunTableCompV1",data() {return {// 表格对象   -- 1tableObj: {http: {url: undefined,params: {},result: {list: undefined,total: undefined}},pageNum: 1,pageSize: 10,total: 0,columns: []},tableData: []}},// 接收父组件传递过来的值props: {// 接收父组件传递过来的data数据,类型为Object   -- 2data: Object},watch: {// 监控父组件中的data,保证子组件中的tableObj与父组件一致   -- 3data: {deep: true, // 深度监控immediate: true, // 在组件创建时立即触发handler(newVal, oldVal) {this.init(newVal) // 初始化}}},// 挂载之前加载数据beforeMount() {this.load()},methods: {// 计算序号calIndex(index) {return (this.tableObj.pageNum - 1) * (this.tableObj.pageSize) + index + 1},// 构建查询参数buildParams() {const params = this.tableObj.http.paramsparams.pageNum = this.tableObj.pageNumparams.pageSize = this.tableObj.pageSizereturn params},// 解析构建结果 - 为了适配 list: 'data.records',做一下处理buildResult(data, key) {const keys = key.split('.')let res = datafor (const key of keys) {res = res[key]}return res},// 加载后端数据load() {// request对axios进行了一层封装request.post(this.tableObj.http.url, this.buildParams()).then(pageObj => {// 后端返回结果,需要的字段在哪不写死this.tableData = this.buildResult(pageObj, this.tableObj.http.result.list)this.tableObj.total = this.buildResult(pageObj, this.tableObj.http.result.total)})},// 更改每页数量handleSizeChange(val) {this.tableObj.pageSize = valthis.tableObj.pageNum = 1this.load()},// 页码切换handleCurrentChange(val) {this.tableObj.pageNum = valthis.load()},// 多选handleSelectionChange(val) {this.multipleSelection = val;},// 初始化方法   -- 4init(newVal) {for (const key in newVal) {// 如果父组件传的值能与tableObj的属性匹配,比如父子组件都有tableObj.columns,则会进入这个ifif (Object.keys(this.tableObj).includes(key)) {// 比如:tableObj.columns = newVal.columnsthis.tableObj[key] = newVal[key]}}}}
}
</script><style scoped></style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/508496.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java基础 - 7 - 常用API(三)

API&#xff08;全称 Application Programming Interface&#xff1a;应用程序编程接口&#xff09; API就是Java帮我们已经写好的一些程序&#xff0c;如类、方法等&#xff0c;可以直接拿过来用 JDK8 API文档&#xff1a;Java Platform SE 8 一. JDK8之前传统的日期、时间 …

并行和并发的区别

并行和并发的区别是并行指的是多个任务在同一时间点上同时执行&#xff0c;而并发指的是多个任务在同一时间段内交替执行。并行需要多个处理器或者多核处理器&#xff0c;每个任务都有独立的资源&#xff0c;不会互相干扰。并发可以在单核或者多核处理器上实现&#xff0c;多个…

【c++】继承深度解剖

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大二&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么事继承&#xff0c;基类和派生类的使用和…

百度诉闪速推公司涉“万词霸屏”不正当竞争纠纷案审理结果

交叉口讯 5月13日&#xff0c;江苏省高级人民法院知识产权庭公布百度诉闪推公司涉及“万磁霸屏”不正当竞争纠纷一案审理结果&#xff1a;判决闪推公司应立即停止涉案的不正当竞争行为。 &#xff0c;公司在其公司官网发布声明&#xff0c;消除影响&#xff0c;并赔偿百度经济损…

码界深潜:全面解读软件工程的艺术与科学

&#x1f3e1; 基石构筑篇——软件工程基础理论及技能 &#x1f522; 编程语言选型与精修 于软件工程之浩瀚宇宙中&#xff0c;编程语言犹如各色画笔&#xff0c;每种语言的特性对应不同的创作领域。譬如Java倚仗跨平台兼容性和强大的面向对象机制&#xff0c;在企业级应用程序…

数字革命的浪潮:Web3如何改变一切

随着数字技术的不断发展&#xff0c;人类社会正迎来一场前所未有的数字革命浪潮。在这个浪潮中&#xff0c;Web3技术以其去中心化、安全、透明的特性&#xff0c;正在逐渐改变着我们的生活方式、商业模式以及社会结构。本文将深入探讨Web3技术如何改变一切&#xff0c;以及其所…

群体风暴之锤(War3地图编辑器)

文章目录 0、大致原理1、创建隐形单位2、新事件开端3、环境→新条件4、动作4.1、单位组4.1.1、圆范围内单位4.1.2、指定条件 4.2、对单位组内的所有单位释放风暴之锤 0、大致原理 真MK向目标点释放风暴之锤时选定&#xff08;以技能释放点为圆心&#xff0c;设定半径&#xff0…

Myqsort:基于冒泡排序算法的C语言实现

我们将详细介绍一个基于冒泡排序算法的自定义排序函数——Mysqrt。该函数通过使用用户提供的比较函数进行元素间的比较&#xff0c;并结合swap交换函数对任意类型的数据进行排序。下面是对代码的逐行解析。 逻辑导图 代码实现 // 头文件 #include<stdio.h>// 定义比较函…

谨用ArrayList中的subList方法

谨用ArrayList中的subList方法 规范一&#xff1a; ArrayList 的 subList 结果不可强转成 ArrayList&#xff0c;否则会抛出 ClassCastException 异常&#xff1a; public static void test7() {List<Integer> list new ArrayList<>();list.add(1);list.add(2);…

【数据分享】1979~2020年MSWEP降水数据集

各位同学们好&#xff0c;今天和大伙儿分享的是1979~2020年MSWEP降水数据集。如果大家有下载处理数据等方面的问题&#xff0c;您可以私信或者评论。 Beck, H. E., E. F. Wood, M. Pan, C. K. Fisher, D. G. Miralles, A. I. J. M. van Dijk, T. R. McVicar, and R. F. Adler, …

三、低代码平台-单据配置(单表增删改查)

一、业务效果图 主界面 二、配置过程简介 配置流程&#xff1a;业务表设计 -》业务对象建立-》业务单据配置-》菜单配置。 a、业务表设计 b、业务对象建立 c、业务单据配置 功能路径&#xff1a;低代码开发平台/业务开发配置/单据配置维护 d、菜单配置

【数据结构和算法】根据前序、中序、后序来确定一颗二叉树

目录 0 引言1 确定二叉树结构的方式1.1 前序和中序1.2 后序和中序1.3 前序和后序&#xff1a;无法确定结构 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;计算机四大基础专栏&#x1f4dc; 其他章节&#xff1a;网络快速入门系列、计网概述、计网…