首页 > 其他分享 >vue+elementUI-Table,实现自定义表格列效果

vue+elementUI-Table,实现自定义表格列效果

时间:2022-10-26 10:56:11浏览次数:57  
标签:vue name 自定义 elementUI list prop item 表格 id

都是日常的工作小结,编写不易,转载请注明出处~考虑到会看我博客的都是和我一样的小白,尽量写细一些,有问题可在评论区留言

一 实现原理

1.1 一般我们在写elementUI表格代码时,都可以通过v-if来控制某个列要不要隐藏,因为我的写表格代码时都是用v-for来写,所以可以在循环数组中设置哪一个列隐藏,在下面的代码中我就是通过show来判断,当循环到某一项,他的show===false时,这一列就隐藏。

1.2 表格演示代码(elementUI文档直接改动的,手敲的没跑过)

点击查看代码
<template>
    <el-table
      :data="tableData"
      style="width: 100%">
        <template v-for="item in tableForList">
          <el-table-column
            :key="item.key"
            :prop="item.prop"
            :label="item.label"
            :width="item.width"
            :min-width="item.minWidth"
            :align="item.align ? item.align : 'center'"
            :show-overflow-tooltip="!item.tooltip"
            v-if="item.show !== false"
          ></el-table-column>
        </template>
    </el-table>
  </template>

  <script>
    export default {
      data() {
        return {
          tableData: [{
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          }, {
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          }, {
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          }, {
            date: '2016-05-03',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1516 弄'
          }],
          tableForList:[{
          prop: "active",
          label: "操作",
          width: "120",
          fixed: true,
        },
        {
          prop: "id",
          label: "编号",
          width: "140",
        },
        {
          prop: "name",
          label: "名称",
          width: "180",
          show: false
        },]

        }
      }
    }
  </script>

二 实现方式

如果直接在代码里写死循环数组是不灵活的,也达不到我们想要的目的,所以我们必须要把循环数组展现给用户看,让用户来设置。用户设置后,我们要保存用户的配置到数据库,下一次用户再点到这个页面,第一件事情是去读数据库里用户的表格配置,从而改变我们默认的循环数组里每一项的show属性。考虑到通用问题,所以我做成了组件TableSelectColumn(我是全局注册组件的,不需要每个页面引入,引入方式根据自己的项目来)。先是使用TableSelectColumn,把组件放到"操作"列的旁边。把循环数组传入到组件中

表格效果图:

点击配置按钮,进入配置界面效果图:

流程如下:
①用户进入A模块表格页面-->
②读取数据库用户是否有设置,如果没有,就按默认的tableForList展示,如果有就把用户设置的隐藏列更新到tableForList中被设置的列的show属性(在created中实现这一步)-->
③用户点击设置按钮-->
④通过选择等方式去设置可见列(相当于设置tableForList每一项的show属性),点击保存-->
⑤保存到数据库,并且更新到当前列表-->
⑥下一次在进入,回到第一步

2.1 表格引用代码
<template>
    <el-table
      :data="tableData"
      style="width: 100%">
        <template v-for="item in tableForList">
          <el-table-column
            :key="item.key"
            :prop="item.prop"
            :label="item.label"
            :width="item.width"
            :min-width="item.minWidth"
            :align="item.align ? item.align : 'center'"
            :show-overflow-tooltip="!item.tooltip"
            v-if="item.show !== false"
          >
            <template slot="header" v-if="item.prop === 'active'">
              <template>
                操作
                <TableSelectColumn
                  ref="tableSelectColumn"
                  :list.sync="tableForList"
                  :name="'projectPrice'"
                  :loadingTime="2000"
                  :tableRef="$refs.queryTable"
                />
              </template>
            </template>
          </el-table-column>
        </template>
    </el-table>
  </template>

  <script>
    export default {
      data() {
        return {
          tableData: [{
            id: '1',
            date: '2016-05-02',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1518 弄'
          }, {
            id: '2',
            date: '2016-05-04',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1517 弄'
          }, {
            id: '3',
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          }],
          tableForList:[{
          prop: "active",
          label: "操作",
          width: "120",
          fixed: true,
        },
        {
          prop: "id",
          label: "编号",
          width: "140",
        },
        {
          prop: "name",
          label: "名称",
          width: "180",
          show: false
        },],
        created() { 
       //表格第一次生成时要去读取这个用户在数据库的配置
           this.$nextTick(() => {
       this.$refs.tableSelectColumn[0].initTable();
       });
         },

        }
      }
    }
  </script>
2.2 TableSelectColumn组件代码
<template>
  <!-- 使用此组件的表格,不要使用min-width属性,会在表格列隐藏/显示时出现错位情况,使用doLayout也没有用。
不要在created里调用接口,在表格列头中使用自定义组件会重复注册组件,导致created重复执行。 -->
  <div style="display: inline-block">
    <el-button
      type="text"
      icon="el-icon-setting"
      @click="onClick"
      size="mini"
    ></el-button>
    <el-dialog
      title="设置可见列"
      :visible.sync="visible"
      :before-close="handleClose"
      :close-on-click-modal="false"
      lock-scroll
      append-to-body
      width="650px"
    >
      <el-transfer
        :filterable="true"
        filter-placeholder="请输入列名"
        v-model="selectVal"
        :data="selectList"
        :props="{
          key: 'val',
          label: 'label',
        }"
        :titles="['隐藏列', '可见列']"
        style="margin: 0px 10px 0px 10px"
      >
      </el-transfer>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="handleSubmit">确 认</el-button>
        <el-button @click="handleClose">取 消</el-button>
      </span></el-dialog
    >
  </div>
</template>

<script>
import {
  getTableHideList,
  addTableHideList,
  editTableHideList,
} from "@/api/system/tableHideList";
export default {
  name: "TableSelectColumn",
  props: {
    list: {
      required: true, //必填,列表循环数组
    },
    name: {
      required: true, //必填,列表名称
    },
    fixedColumn: {
      default: () => ["id", "active", "checkedBox"], //选填,不可选择的列名prop数组,不会出现在可见列配置界面
    },
    tableRef: {
      required: true, //选填,表格的ref,表格会出现错乱情况的可通过ref使用doLayout对表格重新布局
    },
    loadingTime: {
      default: 1000, //选填,设置后的遮罩时间,个别复杂的表格可以设置长一些
    },
    initMethods: {
      type: Function,
      default: undefined, //选填,个别表格需要在初始化时做其他处理的,就把方法传进来
    },
    updateMethods: {
      type: Function,
      default: undefined, //选填,个别表格需要在重新设置可见列后做其他处理的,就把方法传进来
    },
  },
  data() {
    return {
      form: {
        name: undefined,
        id: undefined,
        hideList: undefined,
        createBy: undefined,
      },
      api: {
        list: getTableHideList,
        add: addTableHideList,
        edit: editTableHideList,
      },
      visible: false,
      selectVal: [],
      selectList: [],
    };
  },
  created() {
    //在elementUI使用自定义组件,created会重复执行
    this.form.createBy = this.$store.getters.name;
    this.form.name = this.name;
  },
  methods: {
    //获取隐藏列表,更新到父组件的列表数据
    initTable() {
      this.api.list(this.form).then((response) => {
        if (response.rows.length > 0) {
          this.form.id = response.rows[0].id;
          let hideList = response.rows[0].hideList.split(",");
          let list = JSON.parse(JSON.stringify(this.list));
          list.map((item) => {
            if (hideList.includes(item.prop)) {
              item.show = false;
            }
          });
          // console.log(hideList);
          // console.log(list);
          this.$emit("update:list", list);
          if (this.initMethods) {
            this.initMethods();
          }
        }
      });
    },
    //提交
    handleSubmit() {
      const loading = this.$loading({
        lock: true,
        text: "正在配置表格列,请稍等",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
      });
      //保存隐藏列表
      let list = JSON.parse(JSON.stringify(this.list));
      this.form.hideList = "";
      list.forEach((item) => {
        if (this.selectVal.includes(item.prop)) {
          item.show = true;
        } else if (!this.fixedColumn.includes(item.prop)) {
          item.show = false;
          this.form.hideList += item.prop + ",";
        }
      });
      this.api[this.form.id ? "edit" : "add"](this.form)
        .then(() => {
          this.$emit("update:list", list);
          if (this.updateMethods) {
            this.updateMethods();
          }
          this.$nextTick(() => {
            setTimeout(() => {
              loading.close();
              this.handleClose();
            }, this.loadingTime);
          });
        })
        .catch(() => {
          loading.close();
        });
    },
    //打开配置界面
    onClick() {
      //获取最新的配置项
      this.api.list(this.form).then((response) => {
        this.visible = true;
        if (response.rows.length > 0) {
          this.form.id = response.rows[0].id;
        }
        this.selectVal = [];
        this.selectList = [];
        this.list.map((item) => {
          if (!this.fixedColumn.includes(item.prop)) {
            this.selectList.push({
              val: item.prop,
              label: item.label,
            });
            if (item.show !== false) {
              this.selectVal.push(item.prop);
            }
          }
        });
      });
    },
    handleClose() {
      this.visible = false;
      this.$nextTick(() => {
        if (this.tableRef && this.tableRef.doLayout) {
          this.tableRef.doLayout();
        }
      });
    },
  },
  watch: {
    // tableRef: function (val) {},
  },
};
</script>

<style>
</style>

三 数据库建表参考

因为我的项目每一个模块都有一张表,每个人又有自己的配置,所以我主要是根据name和create_by去查这个人的hide_list,hide_list是隐藏列,以字符串的形式存储,例如
hide_list:'id,name'

标签:vue,name,自定义,elementUI,list,prop,item,表格,id
From: https://www.cnblogs.com/loveniko/p/16827503.html

相关文章