Vue -el-table表格动态控制表头动态展示数据(控制每一列展示)
前言
最近在实际开发中我们遇到一个需求是用户自己控制键值来生成对应表格数据。
换个思路就是我们还是正常查询数据,需要一个开关页面来动态改变表格展示每一列。
我们需要一个开关页面,里面有多选,确定重置取消,确定时把选中数据传递给父组件,动态数据for循环
最好是以封装成组件的形式,可以使代码减少,别的地方也可以用。组件全局注册直接用(主页文章有)
细节
1.可以直接让后端以分页形式把所有需要的字段都返来,最好可以加一个序号。
2.在打开子组件的时候,把默认选中的字段表头重新赋值一次,因为直接在data里面写死的话,子组件侦听器侦听不到,
3.在父组件页面打开的时候可以在month展示一次默认选中数据表格,用户体验较好。
代码如下-可直接复制
父组件
<template>
<div class="content">
<!-- 标题 -->
<div class="title">维保统计报表</div>
<!-- 搜索 -->
<el-form class="search" :inline="true" :model="pageInfo" size="mini">
<el-form-item label="工单类型:">
<el-input v-model="pageInfo.data" placeholder=""></el-input>
</el-form-item>
<el-form-item label="维保小组:">
<el-input v-model="pageInfo.data" placeholder=""></el-input>
</el-form-item>
<el-form-item label="完成情况:">
<el-input v-model="pageInfo.data" placeholder=""></el-input>
</el-form-item>
<el-form-item label="生成时间:">
<el-input v-model="pageInfo.data" placeholder=""></el-input>
</el-form-item>
<el-form-item>
<el-button @click="onSubmit" icon="el-icon-search" type="primary"
>查询</el-button
>
<el-button @click="showSetting" icon="el-icon-setting" type="primary"
>配置表单</el-button
>
</el-form-item>
</el-form>
<!-- 表格数据 -->
<div class="tables">
<el-table
:data="tableData"
border
stripe
size="mini"
height="100%"
style="width: 100%"
>
<!-- <el-table-column label="序号" width="60" align="center">
<template slot-scope="scope">
{{ (pageInfo.pageNo - 1) * pageInfo.pageSize + scope.$index + 1 }}
</template>
</el-table-column> -->
<el-table-column
v-for="item in showTableColumn"
:key="item.prop"
:fixed="item.fixed"
:align="item.align"
:prop="item.prop"
:min-width="item.minWidth"
:width="item.width"
:show-overflow-tooltip="item.tooltip"
:resizable="item.resizable"
:label="item.label"
/>
</el-table>
</div>
<!-- 配置页面 -->
<key-setting
:visible.sync="isSetting"
:data-arr="AllPropertyArrForManage"
:check-list="checkProp"
:default-arr="DefaultPropertyArrForManage"
@confirm="handleConfirm"
/>
<!-- 分页查询 -->
<div class="pagination">
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="pageInfo.pageNo"
:page-sizes="[15, 30, 50, 100]"
:page-size="pageInfo.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="pageInfo.total"
>
</el-pagination>
</div>
</div>
</template>
<script>
export default {
name: "statics",
data() {
return {
// 分页查询
pageInfo: {
// 总条数
total: 0,
// 当前页
pageNo: 1,
// 每页条数
pageSize: 15,
data: "",
},
// 选中的表头字段
showTableColumn: [],
// 所有数据源
tableData: [
{
serial: "1",
date: "2016-05-02",
age: "28",
gender: "男",
name: "王虎",
address: "上海市普陀区金沙江路 1518 弄",
},
{
serial: "2",
date: "2016-05-04",
age: "20",
gender: "男",
name: "王小虎",
address: "上海市普陀区金沙江路 1517 弄",
},
{
serial: "3",
date: "2016-05-01",
age: "25",
gender: "男",
name: "王二虎",
address: "上海市普陀区金沙江路 1519 弄",
},
{
serial: "4",
date: "2016-05-03",
age: "40",
gender: "男",
name: "王大虎",
address: "上海市普陀区金沙江路 1516 弄",
},
],
// 开关
isSetting: false,
// 所有表头字段字段
AllPropertyArrForManage: [
{
prop: "serial",
label: "序号",
minWidth: "120",
align: "center",
tooltip: true,
resizable: true,
},
{
prop: "date",
label: "日期",
minWidth: "120",
align: "center",
tooltip: true,
resizable: true,
},
{
prop: "age",
label: "年龄",
minWidth: "120",
align: "center",
tooltip: true,
resizable: true,
},
{
prop: "gender",
label: "性别",
minWidth: "120",
align: "center",
tooltip: true,
resizable: true,
},
{
prop: "name",
label: "姓名",
minWidth: "120",
align: "center",
tooltip: true,
resizable: true,
},
{
prop: "address",
label: "地址",
minWidth: "120",
align: "center",
tooltip: true,
resizable: true,
},
],
// 选中字段
checkProp: [],
// 默认选中字段
DefaultPropertyArrForManage: ["name", "age", "serial"],
};
},
created() {},
mounted() {
this.dealTableColumn(this.checkProp);
},
methods: {
// 搜索按钮
onSubmit() {},
// 分页 左右 点击 输入
handleSizeChange(val) {
// console.log(`每页 ${val} 条`);
this.pageInfo.pageSize = val;
// this.loadData();
},
// 分页多少条点击事件
handleCurrentChange(val) {
// console.log(`当前页: ${val}`);
this.pageInfo.pageNo = val;
// this.loadData();
},
// 点击配置图标
showSetting() {
this.isSetting = !this.isSetting;
// 打开表单
if (this.isSetting) {
// 默认选中
// 重新赋值一次,是因为所有数据和默认选中数据是本来就有的,
// 重新赋值一次,子组件就可以侦听到值变化了,就可以使子组件多选选中了
this.checkProp = this.DefaultPropertyArrForManage;
}
},
// 提交确定事件 实际工作中会调接口
handleConfirm(val) {
this.checkProp = val;
this.dealTableColumn(this.checkProp);
},
// 重新渲染table表格
dealTableColumn(arr) {
console.log("执行了", arr);
this.showTableColumn = [];
this.AllPropertyArrForManage.forEach((item) => {
if (arr.indexOf(item.prop) > -1) {
this.showTableColumn.push(item);
}
});
},
},
};
</script>
<style lang="scss" scoped>
.content {
overflow: hidden;
background-color: #fff;
height: 827px;
margin: 35px 0 25px;
padding: 5px 10px;
// 适配谷歌火狐,没有书签栏的上下边距
@media screen and (min-height: 950px) and (max-height: 990px) {
margin-top: 50px;
margin-bottom: 40px;
}
// 适配浏览器全屏模式下的上下边距
@media screen and (min-height: 1070px) {
margin-top: 100px;
height: 887px;
margin-bottom: 60px;
}
.title {
padding-left: 15px;
font-size: 14px;
font-weight: 700;
color: #464c5b;
line-height: 40px;
border: solid 1px #e3e8ee;
background-color: #fff;
border-radius: 4px;
&:hover {
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
border-color: rgb(233, 231, 231);
}
}
.search {
padding: 15px 0 0;
}
.tables {
width: 100%;
height: 595px;
border-top: 2px solid #2da9fa;
border-radius: 2px;
cursor: pointer;
::v-deep .el-table__body tr.current-row > td {
background-color: #fcf0da !important;
}
@media screen and (min-height: 1070px) {
height: 685px;
}
}
.pagination {
// background-color: skyblue;
position: fixed;
bottom: 80px;
right: 120px;
// 适配浏览器全屏模式下的上下边距
@media screen and (min-height: 1070px) {
bottom: 80px;
}
}
}
</style>
子组件
<template>
<div class="wrapper">
<!-- 控制显示隐藏 -->
<el-card :style="{ opacity: visible ? '1' : '0' }">
<div slot="header" style="min-width: 200px">
<span>字段配置</span>
<span class="fr close-btn" @click="$emit('update:visible', false)"
>x</span
>
</div>
<div class="keyconter">
<el-checkbox
v-model="checkAll"
:indeterminate="isIndeterminate"
@change="selectAll"
>全选</el-checkbox
>
<el-checkbox-group
v-model="realList"
class="check-list"
@change="handleCheckedChange"
>
<el-checkbox
v-for="item in dataArr"
:key="item.prop"
:label="item.prop"
:disabled="item.prop == 'name'"
>{{ item.label }}</el-checkbox
>
</el-checkbox-group>
</div>
<div class="footer">
<el-button
type="primary"
size="small"
:disabled="realList.length < 1"
@click="confirm"
>确定</el-button
>
<el-button size="small" @click="reset">重置</el-button>
<el-button size="small" @click="cancel">取消</el-button>
</div>
</el-card>
</div>
</template>
<script>
export default {
name: "KeySetting",
props: {
// 组件开关
visible: {
type: Boolean,
default: false,
},
// 表头字段
dataArr: {
type: Array,
default: () => [],
},
// 选中字段
checkList: {
type: Array,
default: () => [],
},
// 默认选中
defaultArr: {
type: Array,
default: () => [],
},
},
data() {
return {
// 全选按钮选中状态
checkAll: false,
// 多选框选中值
realList: [],
// 判断不确定状态
isIndeterminate: true,
};
},
watch: {
checkList(val) {
console.log("watch", val);
// 监听选中的字段,等于默认字段,就全选
this.realList = val;
if (val.length === this.dataArr.length) {
// 关闭不确定状态
this.isIndeterminate = false;
// 全选
this.checkAll = true;
}
},
},
methods: {
// 全选按钮变化事件
selectAll(val) {
// 为true 全选 为false 选中默认值
this.realList = val
? this.dataArr.map((item) => item.prop)
: this.defaultArr;
// if (val) {
// this.isIndeterminate = false;
// } else {
// this.isIndeterminate = true;
// }
this.isIndeterminate = true;
},
// el-checkbox选中事件
// value 是一个数组,里面是多选绑定的值
handleCheckedChange(value) {
const checkedCount = value.length;
// 赋值全选按钮
// 当选中数组长度等于默认渲染长度就把全选改成勾选状态true
this.checkAll = checkedCount === this.dataArr.length;
// 赋值不确定状态
// 当选中数组长度大于0并且等于默认渲染长度就把不确定状态关闭
this.isIndeterminate =
checkedCount > 0 && checkedCount < this.dataArr.length;
},
// 点击确定
confirm() {
// 把多选框选中值传递给父组件
this.$emit("confirm", this.realList);
// 关闭弹框
this.$emit("update:visible", false);
},
// 点击重置
reset() {
// 把默认选中绑定给多选选中
this.realList = [...this.defaultArr];
// 把不确定状态开启
this.isIndeterminate = true;
// 关闭全选按钮
this.checkAll = false;
},
// 点击取消
cancel() {
// 把多选框值赋值回原来默认的值
this.realList = this.checkList;
// 跟下面这一句是一样效果
// 把默认选中绑定给多选选中
// this.realList = [...this.defaultArr];
// 关闭弹框
this.$emit("update:visible", false);
},
},
};
</script>
<style lang="scss" scoped>
.wrapper {
// background-color: red;
position: fixed;
width: 300px;
height: 500px;
top: 85px;
right: 30px;
z-index: 999;
@media screen and (min-height: 950px) and (max-height: 990px) {
top: 100px;
}
// 适配浏览器全屏模式下的上下边距
@media screen and (min-height: 1070px) {
top: 150px;
}
.el-card {
// background-color: skyblue;
width: 100% !important;
height: 100%;
::v-deep .el-card__body {
min-height: 87%;
// background-color: red;
position: absolute;
}
.footer {
// background-color: red;
position: relative;
left: 20px;
bottom: -315px;
}
}
}
</style>
Vue -el-table表格动态控制表头动态展示数据(控制每一列展示)的更多相关文章
- vue + element ui 表格自定义表头,提供线上demo
前言:工作中用到 vue+element ui 的前端框架,需要使用自定义表头,需要使用 re.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9710826.h ...
- Vue+Element+Table表格动态跨列文章
https://my.oschina.net/u/4772459/blog/4699602 如图所示: 1 <template class="SysRole"> 2 & ...
- html table表格斜线表头的实现方法总汇
在html中给table加一个斜线的表头有时是很有必要的,但是到底该怎么实现这种效果呢?总结了以下几种方法: 1.UI背景图实现 直接去找公司的UI,让她做一张图片,作为背景图片放到这里,然后撑满就可 ...
- table 表格固定表头和第一列、内容可滚动
整理了下: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" c ...
- JS+CSS - table 表格固定表头和第一列、内容可滚动 (转载)
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- vue ele table表格 设置只能勾选一个
table 更改属性设置: <el-table ref="multipleTable" :data="tableData" tooltip-effect= ...
- elementui中 table表格 合并表头
需要实现的效果如图,表格头部合并成一排. 因为总共是4列,所以colSpan =4表示合并4列 头部给个高度,居中一下就ok啦
- 微信小程序 table表格 固定表头和首列 右侧表格可以左右滚动(多种表格演练)
https://blog.csdn.net/m0_61073617/article/details/124430213
- jquery table表格 获取选中的某一行和某一列的值
table class="table table-hover" id="test123"> <tr> <th width="4 ...
- BootstrapBlazor + FreeSql ORM 实战 Table 表格组件维护多表数据 - OneToOne
OneToOne 垂直扩展表字段是很常见的方法, 主表存商品资料, 分表存每个客户对应商品的备注和个性化的价格等等, 本文使用Blazor一步步实现这个简单的需求. 1. 基于实战 10分钟编写数据库 ...
随机推荐
- Dify实战案例:MySQL查询助手!嘎嘎好用
有了 AI 之后,我们在查询数据库的时候就不需要使用数据库客户端或程序(如 Java.Python)来查询了,我们可以直接使用 AI 来查询数据库,并且查询语句都不用你来写了,AI 会自动帮你生成. ...
- kubernetes之RBAC介绍
一.RBAC简单说明 在kubernetes中,授权有6种模式: ABAC(基于属性的访问控制) RBAC(基于角色的访问控制) Webhook Node AlwaysDeny(一直拒绝) Alway ...
- IOS内购数据拉取
目标:拉取app store connect 内购数据拉取,自己做数据报表. 1:api秘钥 接口需要token,token生成需要秘钥.参考官方文档:https://developer.apple. ...
- 西门子成都工厂的DevSecOps实践
大家好,我是Edison. 4月15日,成都.NET线下技术沙龙活动中,我分享了一个主题<西门子成都工厂的DevSecOps实践>,向大家介绍了我们为什么要做DevSecOps 以及 我们 ...
- 基于CAP组件实现补偿事务与消息幂等性
1 补偿事务和幂等性 在微服务架构下,我们会采用异步通信来对各个微服务进行解耦,从而我们会用到消息中间件来传递各个消息. 补偿事务 某些情况下,消费者需要返回值以告诉发布者执行结果,以便于发布者实施一 ...
- 渗透测试工作站搭建:Kali + Wave + Zsh + Tmux + 工具集整合实践
前言 在开始任何渗透测试工作之前,搭建一个可靠高效的工作环境至关重要.这包括组织工具.配置系统,以及确保所有必要资源随时可用.通过尽早建立结构良好的测试基础架构,我们可以减少停机时间.最大程度地减少错 ...
- CF559E Gerald and Path 题解
CF559E Gerald and Path 很困难的 DP 题,状态不是很好想.对于这种线段覆盖类题目,显然先覆盖哪个线段没有影响,我们可以通过按照端点位置升序排序后按照顺序考虑,这样可能会有一些额 ...
- SciTech-EECS-Circuits:电路-Transformer(变压器): 高频变压器 线圈匝数
高频变压器 线圈匝数 与 电压 的关系, 主要是 电磁感应定律, 即变压器 的 电压比 与 其 绕组的匝数比 成正比. 就是: $ \large \text{高频变压器}\ 的\ \text{匝数 ...
- 进阶篇:3.3.1)DFM铸造-压铸件设计
本章目的:设计符合压铸工艺的零件,不再犯简单错误,不必再为反复修改模具而烦恼. 1.基础阅读: 进阶篇:2)DFMA的介绍 进阶篇:2.3)DFMA的运用方法(个人方法) 2.压铸的概念 2.1 压铸 ...
- [SWPUCTF 2021 新生赛]pop
题目源码 <?php error_reporting(0); show_source("index.php"); class w44m{ private $admin = ' ...