本篇文章是优化上一篇配置表格列文章。相当于实现这种效果的第二种方式。上一篇文章地址如下:
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="sortRule(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("勾选传递数据给父组件");
},
// 控制是否开启列的排序
sortRule(flag) {
if (flag == true) {
return "custom";
} else if (flag == false) {
return false;
}
},
// 排序
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>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。