vue前端实现配置化表格el-table列的隐藏与展示(具有记忆功能)

简介: vue前端实现配置化表格el-table列的隐藏与展示(具有记忆功能)

问题描述

这两天产品新加了这样的一个需求:因为el-table的列挺多的,就想加一个配置列的功能,就是在配置面板里面里面有很多复选框,一个复选框对应一个列的名字。勾选复选框,对应列出现,取消勾选,对应列隐藏。点击保存列配置,就会记住用户想要显示的列和想要隐藏的列,下次再进来页面的时候,用户看到的还是用户上次在配置面板勾选的对应的复选框和勾选中的复选框对应就是表格显示的列,未勾选的复选框就是表格要隐藏的列。
话不多说,我们先看一下最终的效果图:

实现思路

思路就是:我们通过vue的监听功能来监听复选框的变化,当复选框发生了变化的时候,我们看对应复选框的选中和未选中的值。选中的为true让对应的列显示、隐藏的为false让对应的列隐藏。当然因为vue是数据的双向绑定的,所以我们就让对应的列的隐藏和表格的隐藏一一对应即可。

html部分图示分析


js部分图示分析

总结

思路就是做配置,然后监听变化。最后是案例完整代码

细心的朋友发现,这里的存储是存到本地的,其实更优化的做法是让后端写一个接口,把对应的列的配置数据通过接口存到数据库,然后初始化再取出来用的。不过思路是一样的,优先推荐存数据库

案例完整代码

<template>
  <div id="app">
    <el-table :data="tableData" border style="width: 100%" ref="table">
      <el-table-column
        fixed
        prop="date"
        label="日期"
        width="150"
        v-if="showColumn.date"
      >
      </el-table-column>
      <el-table-column
        prop="name"
        label="姓名"
        width="120"
        v-if="showColumn.name"
      >
      </el-table-column>
      <el-table-column
        prop="province"
        label="省份"
        width="120"
        v-if="showColumn.provinces"
      >
      </el-table-column>
      <el-table-column
        prop="city"
        label="市区"
        width="120"
        v-if="showColumn.city"
      >
      </el-table-column>
      <el-table-column
        prop="address"
        label="地址"
        width="300"
        v-if="showColumn.adreess"
      >
      </el-table-column>
      <el-table-column
        prop="zip"
        label="邮编"
        width="120"
        v-if="showColumn.zipCode"
      >
      </el-table-column>
      <el-table-column fixed="right" width="100" align="center">
        <template slot="header">
          <i
            class="el-icon-setting"
            style="font-size: 22px; cursor: pointer"
            @click="showColumnOption"
          ></i>
        </template>
        <template slot-scope="scope">
          <el-button @click="handleClick(scope.row)" type="text" size="small"
            >查看</el-button
          >
          <el-button type="text" size="small">编辑</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 配置列面板 -->
    <transition name="fade">
      <div class="columnOption" v-show="isShowColumn">
        <div class="content">
          <div class="head">选择显示字段</div>
          <div class="body">
            <el-checkbox v-model="checkList.date" disabled>日期</el-checkbox>
            <el-checkbox v-model="checkList.name">姓名</el-checkbox>
            <el-checkbox v-model="checkList.provinces">省份</el-checkbox>
            <el-checkbox v-model="checkList.city">市区</el-checkbox>
            <el-checkbox v-model="checkList.adreess">地址</el-checkbox>
            <el-checkbox v-model="checkList.zipCode">邮编</el-checkbox>
          </div>
          <div class="footer">
            <el-button size="small" type="primary" plain @click="saveColumn"
              >保存列配置</el-button
            >
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isShowColumn: false,
      tableData: [
        {
          date: "2016-05-02",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区金沙江路 1518 弄",
          zip: 200333,
        },
        {
          date: "2016-05-04",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区金沙江路 1517 弄",
          zip: 200333,
        },
        {
          date: "2016-05-01",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区金沙江路 1519 弄",
          zip: 200333,
        },
        {
          date: "2016-05-03",
          name: "王小虎",
          province: "上海",
          city: "普陀区",
          address: "上海市普陀区金沙江路 1516 弄",
          zip: 200333,
        },
      ],
      // 列的配置化对象,存储配置信息
      checkList: {},
      showColumn: {
        date: true,
        name: true,
        provinces: true,
        city: true,
        adreess: true,
        zipCode: true,
      },
    };
  },
  watch: {
    // 监听复选框配置列所有的变化
    checkList: {
      handler: function (newnew, oldold) {
        // console.log(newnew); 
        this.showColumn = newnew;
        // 这里需要让表格重新绘制一下,否则会产生固定列错位的情况
        this.$nextTick(() => {
          this.$refs.table.doLayout();
        });
      },
      deep: true,
      immediate: true
    },
  },
  mounted() {
    // 发请求得到checkListInitData的列的名字
    if(localStorage.getItem("columnSet")){
      this.checkList = JSON.parse(localStorage.getItem("columnSet"))
    }else{
      this.checkList = {
        date: true,
        name: true,
        provinces: true,
        city: true,
        adreess: true,
        zipCode: true,
      };
    }
  },
  methods: {
    handleClick(row) {
      console.log(row);
    },
    showColumnOption() {
      this.isShowColumn = true;
    },
    saveColumn() {
      localStorage.setItem("columnSet",JSON.stringify(this.checkList))
      this.isShowColumn = false;
    },
  },
};
</script>

<style lang="less" scoped>
.columnOption {
  position: fixed;
  z-index: 20;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: row-reverse;
  .content {
    width: 100px;
    height: 100%;
    background-color: rgb(203, 223, 198);
    .head {
      width: 100%;
      height: 44px;
      border-bottom: 1px solid #000;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 12px;
    }
    .body {
      width: 100%;
      height: calc(100% - 88px);
      box-sizing: border-box;
      padding-top: 10px;
      overflow-y: auto;
      .items {
        width: 100%;
        height: 100%;
        overflow-y: auto;
        display: flex;
        flex-direction: column;
        .el-checkbox {
          width: 100%;
          height: 28px;
          line-height: 28px;
          margin-bottom: 14px;
          display: inline-block;
          font-family: PingFang SC;
          font-style: normal;
          font-weight: normal;
          font-size: 14px;
          color: #000;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          box-sizing: border-box;
          padding-left: 14px;
        }
        .el-checkbox:hover {
          background-color: #f5f7fa;
        }
      }
    }
    .footer {
      width: 100%;
      height: 44px;
      border-top: 1px solid #000;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }
}
// 控制淡入淡出效果
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>
各位大佬们,行行好,点个赞呗。[捂脸哭表情]
相关文章
|
1天前
|
前端开发 JavaScript API
阿珊比较Vue和React:两大前端框架的较量
阿珊比较Vue和React:两大前端框架的较量
|
2天前
|
存储 JavaScript 前端开发
使用Vue.js构建交互式前端的技术探索
【5月更文挑战第12天】Vue.js是渐进式前端框架,以其简洁和强大的特性深受开发者喜爱。它聚焦视图层,采用MVVM模式实现数据与视图的双向绑定,简化开发。核心特性包括响应式数据绑定、组件化、模板系统和虚拟DOM。通过创建Vue实例、编写模板及定义方法,可以构建交互式前端,如计数器应用。Vue.js让复杂、交互式的前端开发变得更加高效和易维护。
|
2天前
|
JSON JavaScript 前端开发
vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户
vue的 blob文件下载文件时,后端自定义异常,并返回json错误提示信息,前端捕获信息并展示给用户
|
2天前
|
JSON JavaScript 前端开发
vue前端运行时出现RangeError: Maximum call stack size exceeded
vue前端运行时出现RangeError: Maximum call stack size exceeded
15 4
|
2天前
|
JavaScript 前端开发
vue前端展示【1】
vue前端展示【1】
8 1
|
2天前
|
JavaScript
vue3表格编辑(数据回显)和删除功能实现
vue3表格编辑(数据回显)和删除功能实现
13 1
|
2天前
|
存储 JavaScript 前端开发
使用vue实现一个添加和编辑的功能
使用vue实现一个添加和编辑的功能
13 1
|
2天前
|
JSON JavaScript Java
从前端Vue到后端Spring Boot:接收JSON数据的正确姿势
从前端Vue到后端Spring Boot:接收JSON数据的正确姿势
25 0
|
2天前
|
前端开发 JavaScript 开发者
【专栏:HTML与CSS前端技术趋势篇】前端框架(React/Vue/Angular)与HTML/CSS的结合使用
【4月更文挑战第30天】前端框架React、Vue和Angular助力UI开发,通过组件化、状态管理和虚拟DOM提升效率。这些框架与HTML/CSS结合,使用模板语法、样式管理及组件化思想。未来趋势包括框架简化、Web组件标准采用和CSS在框架中角色的演变。开发者需紧跟技术发展,掌握新工具,提升开发效能。
|
2天前
|
JSON JavaScript 前端开发
前端框架vue的样式操作,以及vue提供的属性功能应用实战
前端框架vue的样式操作,以及vue提供的属性功能应用实战