乐趣区

关于前端:vue前端实现配置化表格列的显示与隐藏方式二

本篇文章是优化上一篇配置表格列文章。相当于实现这种成果的第二种形式。上一篇文章地址如下:
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>
退出移动版