本篇文章是优化上一篇配置表格列文章。相当于实现这种成果的第二种形式。上一篇文章地址如下:
https://segmentfault.com/a/11…
问题形容
当表格列过多的时候,产品说加一个配置列的性能吧。即勾选了,让其显示。不勾选让其暗藏。下次关上浏览器的时候,还保留上一次的表格列的显示暗藏状态。
效果图附上
代码附上
代码正文写了思路了呢,其实也很简略
子组件表格组件
<template>
<div class="box">
<el-table
:data="tableData"
border
style="width: 100%"
@selection-change="handleSelectionChange"
@sort-change="sortChange"
>
<!-- 复选框列
复选框列和索引列因为有的显示有的不显示,所以咱们应用一个 v -if 去管制它,v-if 的标识取决于父组件(援用这个组件的组件)传递过去的标识。子组件也就是
咱们封装的这个 myTable 组件用 props 接管一下又因为复选框要有勾选工夫所以
@select-change 事件不能落下
-->
<el-table-column
v-if="isShowCheckbox == true"
type="selection"
width="48"
fixed
></el-table-column>
<!-- 索引列 -->
<el-table-column
v-if="isShowIndex == true"
label="序号"
type="index"
width="50"
fixed
>
</el-table-column>
<!-- 主内容列
主内容列的表头就是 label,表头列对应的数据就是 prop,所以父组件能够传递过去
一个数组,外面的每一项就是 label 的名字和 prop 对应的值。通过 v -for 就动静了出现了
sortable 为布尔值管制是否开启以后行的排序功能。-->
<!-- 咱们通过父组件表头数组中的 isHidden 来实现中的列的显示与暗藏,当咱们勾选复选框点击确定当前
能够去更改表头数组对应我的项目的 isHidden 属性
v-for 和 v -if 不能在一块应用,会节约性能。为了防止同时应用 v -for 和 v -if 能够再套一层 template,template 不会生成 dom 元素。这样的话就解决问题了
-->
<template v-for="(item, index) in tableHeaderTitle">
<el-table-column
:prop="item.propName"
:label="item.labelName"
:key="index"
:sortable="item.isSort"
v-if="item.isHidden == false"
>
</el-table-column>
</template>
</el-table>
</div>
</template>
<script>
export default {
name: "myTable",
props: {
// 父组件传递过去的表头的数组数据
tableHeaderTitle: {
type: Array,
default: [],},
// 父组件传递过去的表内容的数组数据
// 留神:表头内容数据和表内容数据有关联的
tableData: {
type: Array,
default: [],},
// 父组件传递过去的是否展现复选框列的标识
isShowCheckbox: {
type: Boolean,
default: false,
},
// 父组件传递过去的是否展现序号索引列的标识
isShowIndex: {
type: Boolean,
default: false,
},
},
methods: {
// 勾选当前,要把勾选的这一行的数据传递给父组件,以供应用
handleSelectionChange(checked) {console.log("勾选传递数据给父组件");
},
// 排序
sortChange(sortInfo) {console.log("排序形式", sortInfo.order);
console.log("排序字段", sortInfo.prop);
},
},
};
</script>
父组件
<template>
<div id="app">
<!-- 简略封装一个表格的全局组件并注册应用,不便 coding -->
<my-table
:tableHeaderTitle="tableHeaderTitle"
:tableData="tableData"
:isShowCheckbox="isShowCheckbox"
:isShowIndex="isShowIndex"
></my-table>
<br />
<br />
<br />
<div class="setColumn">
<el-checkbox
v-model="item.showColumn"
v-for="(item, index) in columnArr"
:key="index"
>{{item.title}}</el-checkbox
>
<br />
<el-button @click="confirm" size="mini" type="primary"> 确认配置列 </el-button>
</div>
</div>
</template>
<script>
export default {data() {
return {
// 管制表头的显示暗藏
columnArr: [],
// 模仿表头数组数据,理论可发申请获取,也能够前端固定这样写。tableHeaderTitle: [],
// 模仿表内容数据,表内容数据要发申请获取
tableData: [
{
id: "11111",
name: "孙悟空",
age: 500,
gender: "男",
height: "七尺男儿",
weight: "三百吨",
like: "桃子",
address: "花果山水帘洞",
},
{
id: "22222",
name: "猪八戒",
age: 88,
gender: "男",
height: "七尺男儿",
weight: "八百吨",
like: "肉包子",
address: "高老庄",
},
{
id: "33333",
name: "沙和尚",
age: 1000,
gender: "男",
height: "七尺男儿",
weight: "三百吨",
like: "鱼",
address: "通天河",
},
],
// 是否展现复选框列
isShowCheckbox: true,
// 是否展现序号索引列
isShowIndex: true,
};
},
mounted() {
// 如果批改了配置列,本地有,就用本地的批改的配置列的数据
if (localStorage.getItem("headArr")) {this.columnArr = JSON.parse(localStorage.getItem("columnArr"));
this.tableHeaderTitle = JSON.parse(localStorage.getItem("headArr"))
}
// 如果没有批改配置列,就还用初始的数据,初始状况下,默认所有都显示
else {
this.columnArr = [
{
title: "姓名",
showColumn: true,
},
{
title: "年龄",
showColumn: true,
},
{
title: "性别",
showColumn: true,
},
{
title: "身高",
showColumn: true,
},
{
title: "体重",
showColumn: true,
},
{
title: "喜好",
showColumn: true,
},
{
title: "住址",
showColumn: true,
},
];
this.tableHeaderTitle = [
{
propName: "name",
labelName: "姓名",
isSort: true,
isHidden: false,
},
{
propName: "age",
labelName: "年龄",
isSort: true,
isHidden: false,
},
{
propName: "gender",
labelName: "性别",
isSort: true,
isHidden: false,
},
{
propName: "height",
labelName: "身高",
isSort: false,
isHidden: false,
},
{
propName: "weight",
labelName: "体重",
isSort: false,
isHidden: false,
},
{
propName: "like",
labelName: "喜好",
isSort: false,
isHidden: false,
},
{
propName: "address",
labelName: "住址",
isSort: false,
isHidden: false,
},
]
}
},
methods: {confirm() {
/*
分为两个数组,选中的数组(显示数组)showshow、和未选中的数组(暗藏数组)hidehide。选中的要显示,未选中的去暗藏掉。选中数组和未选中数组外面寄存的是 title 名字
通过批改表头的 isHidden 属性来管制列的显示和暗藏
*/
let showshow = [];
let hidehide = [];
this.columnArr.forEach((item) => {if (item.showColumn == true) {showshow.push(item.title);
} else {hidehide.push(item.title);
}
});
// 遍历显示数组,依据显示数组中的名字去批改对应表头数组的对象项的 isHidden 属性为 false,// 为 false 就是不暗藏列,也就是显示列
for (let i = 0; i < showshow.length; i++) {for (let j = 0; j < this.tableHeaderTitle.length; j++) {if (showshow[i] == this.tableHeaderTitle[j].labelName) {this.tableHeaderTitle[j].isHidden = false;
}
}
}
// 遍历暗藏数组,思路同上
for (let i = 0; i < hidehide.length; i++) {for (let j = 0; j < this.tableHeaderTitle.length; j++) {if (hidehide[i] == this.tableHeaderTitle[j].labelName) {this.tableHeaderTitle[j].isHidden = true;
}
}
}
// 最初本地存一份,永不失落
localStorage.setItem("headArr", JSON.stringify(this.tableHeaderTitle));
localStorage.setItem("columnArr", JSON.stringify(this.columnArr));
},
},
};
</script>
<style lang="less" scoped>
#app {
width: 100%;
min-height: 100vh;
box-sizing: border-box;
padding: 50px;
.setColumn {background-color: #e9e9e9;}
}
</style>