Element UI 组件Table 使用fixed固定列,动态

2023-03-27  本文已影响0人  第二心跳
需求描述:

1、项目需求在手机上展示一个列表很长数据很多的类似excle的表格内容,
2、需要固定第一列,并且每个单元格的数据添加 展开/收起 按钮 来控制显示文字长度效果如下


1.jpeg
问题描述:

1、由于固定列导致数据的最后一行点击展开后显示不全类似被 overflow:hidden 一样
2、表格内容使用了element table 的插槽,插槽内使用的自定义组件

<el-table-column prop="startState" label="开工情况" width="110" :align="center" :height="fixedColumnHeight">
    <template slot-scope="scope">
       <cpnRow :rowData="scope.row" rowName="startState" length="5"></cpnRow>
    </template>
</el-table-column>
解决办法:

1、给table 标签添加

:row-class-name  //添加行类名
:row-style       //添加行样式
@row-click       //添加行点击事件

三个属性,并给父组件添加监听子组件toggleHight方法,代码如下

  <el-table :row-class-name="tableRowClassName" :row-style="tableRowStyle"  @row-click="rowClick"
     data="tableData" style="width: 100%" class="table-fixed" max-height="400"  border>
     <el-table-column prop="startState" label="开工情况" width="110" :align="center" :height="fixedColumnHeight">
       <template slot-scope="scope">
        <!--  子组件  -->
           <cpnRow :rowData="scope.row" rowName="startState" length="5"  @toggleHight="childClick"></cpnRow>
       </template>
     </el-table-column>
   </el-table>

子组件接收父组件传值,判断展示当前对象的哪个属性值,及展示的文字长度内容高度

<template>
  <div>
     <!--  判断规定的长度,超长截取,不超长正常展示  -->
    <span ref="mySpan" v-if="String(value).length > len">
      <span v-show="show">
        {{ value }}
        <span class="auto-btn" @click="toggleShow()">{{ show ? "收起" : "展开" }}</span>
      </span>
      <span v-show="!show">
        <!--  超长截取  -->
        {{ value.slice(0, len) }}
        <span class="auto-btn" @click="toggleShow()">{{ show ? "收起" : "展开" }}</span>
      </span>
    </span>
    <span v-else>
<!--  不超长正常展示  -->
      {{ value }}
    </span>
  </div>
</template>
<script>
export default {
  data() {
    return {
      row: "",
      value: "",
      show: false,
      valuelength: 10,
      len: 10,
    };
  },
  props: {
    rowData: Object,  //接收父组件传的当前行的数据
    rowName: String,  //接收父组件传的当前组件应展示数据的那个属性
    length: String,   // 接收父组件定义的当前组件应展示多少字符
  },
  updated() {
    this.$nextTick(() => {//监听组件内容高度
      const height = this.$refs.mySpan.offsetHeight;
      this.$emit("toggleHight", height);
    });
  },
  created() {
    this.row = this.rowData;
    this.valuelength = this.length;
    this.show = this.rowData.show;
    this.len = parseInt(this.valuelength);
    let item = this.row;
    let name = this.rowName;
    for (var key in item) {
      if (item.hasOwnProperty(key)) {
        if (key == name) { //根据当前接收的name 去匹配当前数据是否有此属性并展示
          this.value = item[key];
        }
      }
    }
  },
  mounted() {},
  methods: {
    toggleShow() {
      this.show = !this.show;
    },
  },
};
</script>

1、子组件通过toggleShow方法控制展示内容
2、在computed计算当前内容高度,通过 this.$nextTick() 方法 回调重新获取DOM更新后的高度,并通过toggleHight事件传递当前子组件内容高度给父组件

this.$nextTick() 会在DOM 更新循环之后执行然后等待 DOM 更新)

在父组件methods中定义table标签中调用的方法

 /**childClick、tableRowClassName、tableRowStyle、rowClick
     * 以上四个函授组合用于动态获取组件高度并赋值给收fixed影响的行
     */
   // 监听子组件toggleHight触发当前函数,并传给父组件当前状态下子组件内容高度
    childClick(num) { 
      this.fixedColumnHeight = num + 32;
    },
   // 获取当前具体那一行点击的子组件,并获取行数
    rowClick(row, event, column) {
      this.clickRowIndex = row.index;
    },
   // 通过行方法回调给当前行数据添加一个index属性,并将行数赋值给index
    tableRowClassName({ row, rowIndex }) {
      row.index = rowIndex;
    },
    //通过行样式方法回调判断当前行是否是点击行,如果是将获取的子组件内容高度赋值给当前行
    tableRowStyle({ row, rowIndex }) {
      if (rowIndex === this.clickRowIndex) {
        return {
          height: this.fixedColumnHeight + "px",
        };
      } else {
        return {};
      }
    },

这样做到了单击行展示内容内容高度变化后,固定列的高度、及固定列所在当前行高度,保持和内容高度一致,消除了固定列最后一行内容被遮挡

上一篇下一篇

猜你喜欢

热点阅读