Vue2 + Element UI 封装 Table 递归多层级列表头动态

embedded/2024/10/21 4:06:19/

1、在 components 中创建 HeaderTable 文件夹,在创建 ColumnItem.vue 和 index.vue。

如下:

2、index.vue 代码内容,如下:

<template><div><el-table:data="dataTableData"style="width: 100%"max-height="700":cell-style="{'border-right': '1px solid #C4C6CB','border-bottom': '1px solid #C4C6CB',}":header-cell-style="{'background-color': '#f8f8f9','border-right': '1px solid #C4C6CB','border-bottom': '1px solid #C4C6CB',}"><el-table-columnprop="date"label="时间"width="150"align="center"v-if="flag"></el-table-column><!-- 递归组件 --><template v-if="flag"><ColumnItemv-for="(item,index) in dataHeaders":key="item.label":col="item":maxLength="maxLength"></ColumnItem></template><el-table-columnprop=""width="150"align="center"v-if="showAddBut && flag"><template slot="header" slot-scope="scope"><i class="el-icon-plus" @click="getAdd({})"/></template></el-table-column></el-table><el-drawer:title="title":visible.sync="drawer":size="350"direction="ltr":before-close="handleClose"><el-form:inline="true":model="column"label-position="right"label-width="auto"ref="ruleFormRef":rules="rules"class="demo-form-inline form-padding"><el-form-item label="名称" prop="label"><el-input v-model="column.label" placeholder="请输入名称" clearable /></el-form-item><el-form-item label="宽度" prop="width"><el-inputv-model="column.width"type="number"placeholder="请输入列宽度(不填为自适应)"clearable/></el-form-item><el-form-item label="对齐方式" prop="align"><el-selectv-model="column.align"placeholder="请选择对齐方式"clearable><el-option label="左对齐" value="left" /><el-option label="居中对齐" value="center" /><el-option label="右对齐" value="right" /></el-select></el-form-item><el-form-item label="映射变量" prop="prop"><el-cascaderv-model="column.prop":options="options":props="optionProps"@change="handleChange"></el-cascader></el-form-item></el-form><div class="drawer-footer"><el-button @click="handleClose">取消</el-button><el-button type="primary" :loading="loading" @click="handleSubmit">{{ submitText }}</el-button></div></el-drawer></div>
</template><script>
import { EventBus } from "../../utils/event-bus.js";
import ColumnItem from './ColumnItem.vue';
import { apiEditHeaderTable, apiGetList, apiGetTreeselect } from "@/api/headerTable/index.js";
export default {name: 'CustomElTable',components: {ColumnItem},props: {// 表头数据headers: {type: Array,required: true},// 表格列表数据tableData: {type: Array,required: true},// 区分哪个页面下的列表tablekey: {type: String,required: true},// 限制新增最大列maxLength: {type: Number,required: false},},data() {return {dataHeaders: this.headers,dataTableData: this.tableData,dataNum: this.num,flag: true, // 为了更新子组件的状态drawer: false,loading: false,column: {label: "",width: "",align: "center",prop: "",},optionProps: { expandTrigger: 'click',value: "id",label: "label",children: "children",},copyCol: {},rules: {label: [{ required: true, message: "请输入名称", trigger: "blur" }],align: [{ required: true, message: "请选择对齐方式", trigger: "blur" }],},title: '新增列',submitText: '新增',options: [],}},computed: {showAddBut() {return this.$store.state.common.headerEditBut}},watch: {headers: {handler(newValue,oldValue) {this.dataHeaders = newValue;}},},methods: {// 删除getDelete(col) {this.$confirm('是否删除?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(_ => {let newHeaders = this.getRecursion(this.dataHeaders,col);console.log("处理完数据的", newHeaders);this.dataHeaders = newHeaders;// 数据更新,更新子组件状态this.flag = false;this.$nextTick(() => {this.flag = true;})EventBus.$emit("getHeaders",this.headers)}).catch(() => {});},// 递归删除getRecursion(arr,col) {arr.map((item,index) => {if(item.label === col.label && item.deep === col.deep) {arr.splice(index,1);return;}if(item.children && item.children.length > 0) {this.getRecursion(item.children,col)}})return arr;},// 新增getAdd(col) {this.drawer = true;this.title = '新增列';this.submitText = '新增';this.column.label = '新增列';this.copyCol = col;},// 编辑getEdit(col) {this.drawer = true;this.title = '编辑列',this.submitText = '保存',this.column.label = col.label;this.copyCol = col;},// 编辑,新增里的取消handleClose() {this.$confirm('内容未保存,确认关闭?','提示',{confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(_ => {this.drawer = false;}).catch(_ => {});},// 编辑,新增里的保存handleSubmit() {let col = this.copyColthis.loading = true;let item = {label: this.column.label,prop: "",width: this.column.width,align: this.column.align,deep: 1,selected: false,children: []}if(this.title === '新增列') {if(!Object.keys(col).length == 0){item.deep = col.deep + 1;col.children.push(item);}else {this.dataHeaders.push(item);}}else {this.flag = false;this.$nextTick(() => {this.flag = true;col.label = this.column.label;col.width = this.column.width;col.align = this.column.align;col.prop = this.column.prop;})}this.loading = false;this.drawer = false;console.log("dataHeaders", this.dataHeaders);// this.handleApi();},// 请求接口,保存表头数据handleApi() {let data = {tableKey: this.tablekey,tableJson: JSON.stringify(this.dataHeaders)}apiEditHeaderTable(data).then(() => {this.loading = false;this.drawer = false;this.$message({message: '编辑成功',type: 'success'});}).catch(() => {this.loading = false;this.drawer = false;this.$message({message: '编辑失败',type: 'error'});})},handlePreserve() {console.log("保存");this.handleApi();},//handleChange(val) {let aa = val[val.length-1]apiGetList({deptId: aa}).then(res => {console.log(">>>>",res);})},handleList() {let data = {}apiGetTreeselect(data).then((res) => {this.options = res.data;})}},mounted() {this.handleList();console.log("tablekey",this.tablekey);EventBus.$on("getDelete",(col) => {this.getDelete(col)});EventBus.$on("getAdd",(col) => {this.getAdd(col)});EventBus.$on("getEdit",(col) => {this.getEdit(col)});EventBus.$on("handlePreserve",() => {this.handlePreserve()});}
}
</script><style lang="scss" scoped>
.scope_p {margin: 0;
}
.i_margin {margin: 0 10px;
}.content-main {.table-title {display: flex;justify-content: space-around;margin-bottom: 10px;> p {flex: 1;font-weight: bold;font-size: 18px;}}.el-input {width: 250px;}.el-select {width: 280px;}
}
.form-padding {padding: 0 20px;
}
.drawer-footer {display: flex;align-items: center;justify-content: center;
}.header-btn {display: flex;align-items: center;justify-content: center;.el-icon-plus {margin-left: 10px;cursor: pointer;}.el-icon-edit {margin-left: 10px;cursor: pointer;}.el-icon-delete {margin-left: 10px;cursor: pointer;}
}.selected {color: #409eff;
}.header-scroll::v-deep {.el-table__header-wrapper {overflow-x: auto;}/* 修改滚动条样式 */::-webkit-scrollbar {height: 8px; /* 设置滚动条宽度 */}::-webkit-scrollbar-track {background-color: #ffffff; /* 设置滚动条轨道背景色 */}::-webkit-scrollbar-thumb {background-color: #ececec; /* 设置滚动条滑块颜色 */border-radius: 4px; /* 设置滚动条滑块圆角 */}::-webkit-scrollbar-thumb:hover {background-color: #e2e2e2; /* 设置滚动条滑块鼠标悬停时颜色 */}
}
.error_label {color: #f56c6c !important;
}
</style>

3、ColumnItem.vue 代码内容,如下:

<template><el-table-column:prop="col.prop":width="col.width":align="col.align"min-width="150"><template slot="header" slot-scope="scope"><p class="scope_p">{{col.label}}</p><div v-if="showAddBut"><i class="el-icon-plus" v-if="col.deep < maxLength" @click="Add(col)"/><i class="el-icon-edit-outline i_margin" @click="Edit(col)"/><i class="el-icon-delete" @click="Delete(col)"/></div></template><!-- 遍历递归 --><template v-for="(item,index) in col.children"><ColumnItem v-if="item.children" :col="item" :key="item.label" :maxLength="maxLength"/></template></el-table-column>
</template><script>
import { EventBus } from "../../utils/event-bus.js";
export default {name: "ColumnItem",props: {col: {type: Object,required: true},maxLength: {type: Number,required: false},},methods: {Add(col) {EventBus.$emit("getAdd",col)},Edit(col) {EventBus.$emit("getEdit",col)},Delete(col) {console.log(col);EventBus.$emit("getDelete",col)}},computed: {showAddBut() {return this.$store.state.common.headerEditBut}},mounted() {},
}
</script><style lang="scss" scoped>
.scope_p {margin: 0;
}
i {cursor: pointer;
}
.i_margin {margin: 0 10px;
}
</style>

4、在 .vue 文件中使用和数据,如下: 

<HeaderTable :headers="headers" :tableData="tableData" :tablekey="tablekey" :maxLength="4"/>
data() {return {headers: [{label: "1",prop: "name",width: "150",align: "center",deep: 1,selected: false,children: [{label: "1-1",prop: "",width: "",align: "center",deep: 2,selected: false,children: [{label: "1-1-1",prop: "",width: "",align: "center",deep: 3,selected: false,children: []}]},{label: "1-2",prop: "",width: "",align: "center",deep: 2,selected: false,children: []}]},{label: "2",prop: "name",width: "150",align: "center",deep: 1,selected: false,children: [{label: "2-1",prop: "",width: "",align: "center",deep: 2,selected: false,children: [{label: "2-1-1",prop: "",width: "",align: "center",deep: 3,selected: false,children: []},{label: "2-1-2",prop: "",width: "",align: "center",deep: 3,selected: false,children: []}]},{label: "2-2",prop: "",width: "",align: "center",deep: 2,selected: false,children: []}]}],tableData: [{date: '2016-05-03',}, {date: '2016-05-02',}, {date: '2016-05-04',}, {date: '2016-05-01',}, {date: '2016-05-08',}, {date: '2016-05-06',}, {date: '2016-05-07', }],}
}

5、效果图,如下:


http://www.ppmy.cn/embedded/45152.html

相关文章

算法第三天力扣第69题:X的平方根

69. x 的平方根 (可点击下面链接或复制网址进行做题) https://leetcode.cn/problems/sqrtx/https://leetcode.cn/problems/sqrtx/ 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 注意:不允许使用任何内…

nn.Embedding使用

nn.Embedding使用 Embedding.weight会从标准正态分布中初始化成大小为&#xff08;num_embeddings, embedding_dim&#xff09;的矩阵 PE矩阵的作用就是替换这个标准正态分布 input中的标号表示从矩阵对应行获取权重来表示单词 # 1.设置embedding结构 max_seq_len 1000 # 句…

L9110S电机控制模块

1.L9110s控制小车前进后退左右 接通VCC&#xff0c;GND 模块电源指示灯亮&#xff0c; 以下资料来源官方&#xff0c;但是仍需我们调制 &#xff08;前进&#xff09;&#xff1a; L1A输入低电平&#xff0c;L1B输入高电平 R1A输入低电平&#xff0c;R1B输入高电平 &a…

Github Page 部署失败

添加 .gitmodules 文件 [submodule "themes/ayer"]path themes/ayerurl https://github.com/Shen-Yu/hexo-theme-ayer.git 添加 .nojekyll 文件

大模型管理工具Ollama搭建及整合springboot

目录 一、Ollama介绍 1.1 什么是Ollama 1.2 Ollama特点与优势 二、Ollama本地部署 2.1 版本选择 2.2 下载安装包 2.3 执行安装 2.4 Ollama常用命令 三、使用Ollama部署千问大模型 3.1 千问大模型介绍 3.2 部署过程 四、springboot接入Ollama 4.1 引入Ollama依赖 4…

Oracle dblink 发现Network 等待事件的分析 enq: KO - fast object checkpoint

所有的sql 通过dblink 查询全部等待中&#xff0c; 同一个SQL 20多个session 在跑&#xff0c;等待事件network&#xff0c;可能怀疑是不是网络断开了&#xff0c;导致没有返回 执行sql 如下&#xff1a; BEGIN Xdblink ; END; 去到dblink 所在的db&#xff0c;发现20多个sql在…

jpeg编码学习

正点原子stm32教程提到过jpeg解码库libjpeg&#xff0c;但是没有提到jpeg编码&#xff0c;我也好奇jpeg编码怎么实现&#xff0c;用代码怎么生成jpeg文件的。所以最近学习了jpeg编码&#xff0c;在这里做记录。 参考文章 jpeg图片格式详解 https://blog.csdn.net/yun_hen/art…

【专利 超音速】一种光伏检测系统

申请号CN202410053901.0公开号&#xff08;公开&#xff09;CN118032774A申请日2024.01.12申请人&#xff08;公开&#xff09;超音速人工智能科技股份有限公司发明人&#xff08;公开&#xff09;张俊峰(总); 叶长春(总); 许春夏 摘要 本发明公开一种光伏检测系统&#xff0…