Element-UI Table实现列表筛选数据及列表嵌套选择框

VUE 框架在 Element UI 的基础上,Table 组件中实现了列表数据的修改功能,支持单选和多选功能,并且列表具备筛选功能。样式如图所示。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

功能介绍

  • 点击table列名实现筛选查询功能
  • 相关性判断点击列表中的正方形实现选择框功能,同时修改列表数据
  • 其他标记点击列表实现复选框功能,列表样式根据选择数据的数量动态适应宽度。

功能实现

相关性判断类单选功能

  • 表头筛选功能
    在表头位置添加了一个 el-popover 弹出框,里面包含了 el-checkbox-group 用于选择不同的相关性判断选项。通过点击表头旁边的图标来打开弹出框并选择筛选条件。点击“查询”按钮时,将关闭弹出框,并执行查询逻辑。
  • 列表数据修改功能
    每行数据旁边都有一个 el-popover,其中包含可点击的不同相关性判断选项。当点击某个选项时,会更新该行数据的相关性判断,并发送请求到后端进行数据更新。
代码
<el-table-column width="60" prop="correlationJudgment">
    <!-- 列数据筛选功能 -->
    <template #header>
        <span class="top-header">相关性<br />判断
            <!-- 弹出框,用于显示相关性判断的选择 -->
            <el-popover 
                @show="correlationJudgmentshowPopover('相关性')" 
                @hide="correlationJudgmenthidePopover" 
                ref="correlationJudgmentPopover" 
                placement="bottom" 
                trigger="click" 
                popper-class="top-popover" 
                :popper-options="{ boundariesElement: 'viewport', removeOnDestroy: true }">
                
                <div class="genePopover-title">相关性判断</div>
                <div class="genePopover-box"> 
                    <div style="padding: 5px 15px">
                        <!-- 多选框组,用于选择相关性判断的选项 -->
                        <el-checkbox-group v-model="correlationJudgmentList">
                            <el-checkbox label="高度相关">高度相关</el-checkbox>
                            <el-checkbox label="其他可疑">其他可疑</el-checkbox><br>
                            <el-checkbox label="参考位点">参考位点</el-checkbox>
                            <el-checkbox label="热点突变">热点突变</el-checkbox><br>
                            <el-checkbox label=""></el-checkbox>
                        </el-checkbox-group>
                    </div>
                </div>
                <div class="popover-footer">
                    <!-- 取消按钮 -->
                    <div class="geneBtnCancel" @click="correlationJudgmentCancelBtn">
                        取消
                    </div>
                    <!-- 查询按钮 -->
                    <div class="geneBtnQuery" @click="correlationJudgmentQueryBtn">
                        查询
                    </div>
                </div>
                <!-- 弹出框的参考内容 -->
                <div slot="reference" class="determine">
                    <img src="../../../assets/images/筛选.png" class="top-img" alt="" v-if="correlationJudgmentList.length == 0" />
                    <img src="../../../assets/images/red.png" class="top-img1" alt="" v-else />
                </div>
            </el-popover>
        </span>
    </template>
    
    <!-- 列表数据修改显示 -->
    <template slot-scope="scope">
        <div class="determine-box">
            <!-- 每一行数据的弹出框 -->
            <el-popover 
                :ref="`popover-${scope.$index}`" 
                placement="left" 
                trigger="click" 
                :offset="30" 
                :popper-options="{ boundariesElement: 'viewport',removeOnDestroy: true }">
                
                <!-- 相关性判断的选项,每个选项都调用 getdetermine 方法 -->
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('高度相关', scope)">
                    高度相关
                </div>
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('其他可疑', scope)">
                    其他可疑
                </div>
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('参考位点', scope)">
                    参考位点
                </div>
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('热点突变', scope)">
                    热点突变
                </div>
                <div style="width: 100px;margin: 0;display: flex;justify-content: center;line-height: 2;" @click="getdetermine('无', scope)"></div>
                <!-- 显示当前行的相关性判断结果 -->
                <div slot="reference" class="determine">
                    {{ scope.row.correlationJudgment }}
                </div>
            </el-popover>
        </div>
    </template>
</el-table-column>
methods:{
   	//悬浮
    correlationJudgmentshowPopover (row) {
      this.titleContent = row;
    },
    //悬浮隐藏
    correlationJudgmenthidePopover () {

    },
    //悬浮取消
    correlationJudgmentCancelBtn () {
      this.$refs.correlationJudgmentPopover.doClose();
    },
    //悬浮查询
    correlationJudgmentQueryBtn () {
      this.pageSize = 10;
      this.pageNum = 1;
      this.getAllParams();
      this.$refs.correlationJudgmentPopover.doClose();
    },
    //选中数据
    getdetermine (val, row) {
      let oldcorrelationJudgment = row.row.correlationJudgment;
      if (val == "无") {
        row.row.correlationJudgment = "";
      }
      let params = {
        参数...
      };
      updateReport(params).then((res) => {
      	this.getList();
      });
      this.$refs[`popover-${row.$index}`].doClose();
      this.$forceUpdate();
    },
}
注释说明:
  • <el-table-column>: 定义表格的列,指定宽度和绑定的数据属性。
  • <template #header>: 自定义表头,包含一个弹出框用于选择相关性判断。
  • <el-popover>: 弹出框组件,用于显示选项和操作按钮。
  • <el-checkbox-group>: 用于多个复选框的分组,允许用户选择多个选项。
  • @click: 事件处理器,触发相应的方法。
  • slot-scope: 用于访问当前行数据(scope),使得每一行可以独立操作。

其他标记复选功能

  • 表头筛选功能
    类似地,在其他标记列的表头位置也添加了一个 el-popover 弹出框,用于选择不同的其他标记。可以选择多个标记,并通过点击“查询”按钮来执行筛选操作。
  • 列表数据修改功能
    每行数据旁边也有一个 el-popover,其中包含可选择的其他标记选项。可以选择或取消选择某些标记,然后当关闭弹出框时,会更新该行数据的其他标记,并发送请求到后端进行数据更新。
代码
<el-table-column width="90" prop="multipleRelevances">
    <!-- 自定义表头 -->
    <template #header>
        <span class="top-header">其他<br />标记
            <!-- 弹出框,用于选择其他标记 -->
            <el-popover 
                @show="multipleRelevanceshowPopover('相关性')" 
                @hide="multipleRelevancehidePopover" 
                ref="multipleRelevancePopover" 
                placement="bottom" 
                trigger="click" 
                popper-class="top-popover" 
                :popper-options="{ boundariesElement: 'viewport', removeOnDestroy: true }">
                
                <div class="genePopover-title">其他标记</div>
                <div class="genePopover-box">
                    <div style="padding: 5px 15px">
                        <!-- 多选框组,用于选择其他标记 -->
                        <el-checkbox-group v-model="multipleRelevanceList">
                            <el-checkbox label="自闭基因">自闭基因</el-checkbox>
                            <el-checkbox label="次要发现">次要发现</el-checkbox><br>
                            <el-checkbox label=""></el-checkbox>
                        </el-checkbox-group>
                    </div>
                </div>
                <div class="popover-footer">
                    <!-- 取消按钮 -->
                    <div class="geneBtnCancel" @click="multipleRelevanceCancelBtn">
                        取消
                    </div>
                    <!-- 查询按钮 -->
                    <div class="geneBtnQuery" @click="multipleRelevanceQueryBtn">
                        查询
                    </div>
                </div>
                <!-- 弹出框的参考内容 -->
                <div slot="reference" class="determine">
                    <img src="../../../assets/images/筛选.png" class="top-img" alt="" v-if="multipleRelevanceList.length == 0" />
                    <img src="../../../assets/images/red.png" class="top-img1" alt="" v-else />
                </div>
            </el-popover>
        </span>
    </template>

    <!-- 列表数据修改显示 -->
    <template slot-scope="scope">
        <div class="determine-box">
            <el-popover 
                @hide="multipleRelevanceHide(scope)" 
                @show="multipleRelevanceClick(scope)" 
                :ref="`popover-${scope.$index}`" 
                placement="left" 
                trigger="click" 
                :offset="30" 
                :popper-options="{ boundariesElement: 'viewport',removeOnDestroy: true }">
                
                <div style="width: 100px;margin-left: 20px;display: flex;justify-content: center;line-height: 2;">
                    <!-- 多选框组,用于选择其他标记 -->
                    <el-checkbox-group v-model="multipleRelevances" @change="handleMultipleRelevanceChange">
                        <el-checkbox label="自闭基因">自闭基因</el-checkbox>
                        <el-checkbox label="次要发现">次要发现</el-checkbox>
                    </el-checkbox-group>
                </div>
                <!-- 弹出框的参考内容,通过数据量动态显示样式宽度 -->
                <div slot="reference" class="determine" :style="'width: '+(scope.row.multipleRelevances && scope.row.multipleRelevances.length > 1 ? 60 : 30) + 'px;'">
                    <span v-for="relevance in scope.row.multipleRelevances" :key="relevance">
                        {{ relevance }}
                    </span>
                </div>
            </el-popover>
        </div>
    </template>
</el-table-column>
注释说明:
  • <el-table-column>: 定义表格的列,指定宽度和绑定的数据属性。
  • <template #header>: 自定义表头,包含一个弹出框用于选择其他标记。
  • <el-popover>: 弹出框组件,用于显示选项和操作按钮。
  • <el-checkbox-group>: 用于多个复选框的分组,允许用户选择多个选项。
  • @click: 事件处理器,触发相应的方法。
  • slot-scope: 用于访问当前行数据(scope),使得每一行可以独立操作。
methods:{
   	//悬浮
    multipleRelevanceshowPopover (row) {
      this.titleContent = row;
    },
    //悬浮隐藏
    multipleRelevancehidePopover () {

    },
    //悬浮取消
    multipleRelevanceCancelBtn () {
      this.$refs.multipleRelevancePopover.doClose();
    },
    //悬浮查询
    multipleRelevanceQueryBtn () {
      this.pageSize = 10;
      this.pageNum = 1;
      this.getAllParams();
      this.$refs.multipleRelevancePopover.doClose();
    },
    //选中数据,进行修改
    multipleRelevanceHide (row) {
      let multipleRelevanceStr = JSON.parse(JSON.stringify(this.multipleRelevances));
      this.multipleRelevances = [];
      let multipleRelevance = multipleRelevanceStr.join(',')
      let oldmultipleRelevance = row.row.multipleRelevance;
      let params = {
        参数...
      };
      updateReport(params).then((res) => {
        this.getList(); 
      });
      this.$refs[`popover-${row.$index}`].doClose();
      this.$forceUpdate();
    },
    //点击时获取数据用于复选框数据回显
    multipleRelevanceClick (row) {
      this.multipleRelevances = row.row.multipleRelevances
    },
    //选中的数据
    handleMultipleRelevanceChange (value) {
      this.multipleRelevances = value
    },
}

页面样式

<style lang="scss">
@import "../../../assets/styles/index.scss";

.el-popover {
  min-width: 100px;
  padding: 0;
  // left: 8px !important;
  font-size: 12px;

  .genePopover-title {
    padding: 0 10px;
    width: 100%;
    background-color: var(--topPopover);
    color: #ffffff;
    height: 30px;
    line-height: 30px;
    border-radius: 4px 4px 0 0;
  }

  .genePopover-box {
    padding: 8px;
    border-bottom: 1px solid #d0d0d0;

    .el-textarea__inner {
      font-size: 13px;
    }

    .title-info {
      padding: 5px 0;
    }
  }

  .genePopover-box {
    max-width: 300px !important;
  }

  .popover-footer {
    display: flex;
    justify-content: flex-end;
    padding: 8px;
    line-height: 1;

    .geneBtnCancel {
      padding: 4px 8px;
      border: 1px solid #d0d0d0;
      border-radius: 3px;
      margin-right: 10px;
    }

    .geneBtnQuery {
      padding: 4px 8px;
      border-radius: 3px;
      background-color: var(--topPopover);
      color: #ffffff;
    }
  }

  .numberOfCasesPopover {
    display: flex;
    align-items: center;
    padding-top: 10px;
    padding-bottom: 20px;

    .el-input--medium .el-input__inner {
      height: 30px;
      line-height: 30px;
    }
  }

  .el-checkbox {
    margin-right: 10px;

    .el-checkbox__label {
      padding-left: 5px;
      font-size: 12px;
    }
  }

  .el-checkbox__input.is-checked .el-checkbox__inner {
    background-color: var(--checkboxColor);
    border-color: var(--checkboxColor);
  }

  .el-checkbox__input.is-checked + .el-checkbox__label {
    color: var(--checkboxColor);
  }

  .el-checkbox__input.is-indeterminate .el-checkbox__inner {
    background-color: var(--checkboxColor);
    border-color: var(--checkboxColor);
  }

  .el-input--medium .el-input__inner {
    height: 30px;
    line-height: 30px;
  }
  .el-input__suffix {
    top: -3px;
  }
  .el-textarea__inner {
    padding-bottom: 15px;
  }

  .el-textarea .el-input__count {
    color: #909399;
    background: #ffffff;
    position: absolute;
    font-size: 12px;
    bottom: 2px;
    right: 20px;
    line-height: 1;
  }
}

.top-popover[x-placement^="bottom"] {
  margin-top: 21px;
  margin-left: 5px;
}

.top-popover[x-placement^="bottom"] .popper__arrow::after {
  border-bottom-color: var(--topPopover) !important;
}

.SNPInDel {
  .el-textarea__inner {
    padding-bottom: 15px;
  }

  .el-table {
    font-size: 12px;
    .el-table__header-wrapper {
      border-radius: 5px 5px 0 0;
    }
    .el-table__header-wrapper,
    .el-table__fixed-header-wrapper {
      th {
        word-break: break-word;
        background-color: #e3e8f1;
        color: #515a6e;
        height: 20px;
        font-size: 12px;
        font-weight: bold;
        padding: 3px 0;
      }
    }

    .el-table__body-wrapper {
      .el-button [class*="el-icon-"] + span {
        margin-left: 1px;
      }
    }

    .el-table--medium .el-table__cell {
      padding: 10px !important;
    }

    .cell {
      padding: 0 !important;
      line-height: 1.1;
      // height: 100%;
      display: flex;
      flex-direction: column;

      p {
        margin: 0 !important;
        height: 100%;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        width: 100%;
      }

      .el-icon-s-open:before {
        content: "";
        color: var(--color);
      }

      .determine-box {
        .determine {
          font-size: 12px;
          display: flex;
          justify-content: center;
          width: 30px;
          // height: 30px;
          min-height: 30px;
          align-items: center;
          color: var(--color);
          background-color: #c4e8ff;
          border: 1px dashed var(--color);
          border-radius: 2px;
          padding: 1px;
          cursor: pointer;
        }
        .determines {
          font-size: 12px;
          display: flex;
          justify-content: center;
          width: 30px;
          // height: 30px;
          min-height: 30px;
          align-items: center;
          color: var(--color);
          background-color: #c4e8ff;
          border: 1px dashed var(--color);
          border-radius: 2px;
          padding: 1px;
          cursor: pointer;
        }
      }
  
    }

    .top-header {
      position: relative;
      height: 40px;
      display: flex;
      align-items: center;

      .top-img {
        position: absolute;
        width: 12px !important;
        bottom: 3px;
        cursor: pointer;
      }
      .top-img1 {
        position: absolute;
        width: 12px !important;
        bottom: 3px;
        cursor: pointer;
      }
    }
  }
}
</style>
Element UITable 组件默认支持分页功能,如果你想实现在跨页情况下进行多选,可以结合其提供的`selection`属性和自定义事件处理。`selection`属性允许你在表格上设置单选或多选模式,你可以通过监听`@selection-change`事件来跟踪用户的选中状态,不论是在哪一页。 以下是实现步骤: 1. 在 Vue 中配置 `element-ui` 的 Table,设置 `selection` 为 `multiple` 或 `row-key` 来保证行级选择(如果你需要基于每个条目的唯一标识符进行多选): ```html <el-table :data="tableData" selection="multiple"> <!-- 表格列 --> </el-table> ``` 2. 在组件内获取和处理选择数据: ```javascript export default { data() { return { tableData: [], // 假设这是你的数据源 selectedItems: [] // 存储选中的行 }; }, methods: { handleSelectionChange(val) { this.selectedItems = val; // 当用户切换选择时,更新selectedItems } }, watch: { $refs: { handler(newRef, oldRef) { if (newRef && newRef.$el) { newRef.$el.addEventListener('selection-change', this.handleSelectionChange); } else if (oldRef) { oldRef.$el.removeEventListener('selection-change', this.handleSelectionChange); } }, deep: true } } } ``` 3. 如果有分页,你需要额外处理每页的数据同步: ```javascript // 假设你有一个分页器 component,如 el-pagination this.pagination.currentPage.value = 1; // 刷新到第一页 this.getTableData(page => { // 获取当前页数据并更新表格及选择 // 更新selectedItems为你在新数据中的选择 }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懒人w

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值