使用el-row、el-col制作表格及表格下方的展开/收起按钮

使用el-row、el-col制作表格及表格下方的展开/收起按钮

效果图如下

  • 动态图

在这里插入图片描述

  • 收起状态
  • 展开状态
  • 无数据状态

功能:

● 默认展示三行数据,超出三行的数据被折叠,点击展开按钮,即可展开
● 如果没有数据,展示内容为:暂无数据,且展开按钮也不显示
● 如果数据不到三行或者只有三行,那么展开按钮不显示

思路:

  • 使用el-rowel-col将表格的雏形可以先绘制出来

    • el-col中的span将一行分为24份
    • 具体样式看下面的css代码
  • 默认展示三行数据,超出三行的数据被折叠

    • 将展示的数据放在一个数组中,使用v-for循环遍历
    • 使用v-show判断index是否小于3,⚠️ 这里不能使用v-if,因为v-forv-if不推荐同时使用
  • 展开与收起的实现

    • 定义一个变量,定义为false,再定义一个方法监听这个值的改变,具体实现看代码
  • 具体实现看代码

为什么v-if和v-for不推荐同时使用

  • v-for指令基于一个数组来渲染一个列表
  • v-for 指令基于一个数组来渲染一个列表
  • v-forv-if优先级高,所以使用的话,每次v-for都会执行v-if,造成不必要的计算,影响性能,尤其是当之需要渲染很小一部分的时候。
<template>
  <div class="overview-system-state">
    <div class="overview-system-state__row">
      <div class="title">{{ labelInfo.title }}</div>
      <div class="set action-link">{{ labelInfo.set }}</div>
    </div>
    <div class="overview-system-state__labels">
      <el-row class="header">
        <el-col :span="2">弱点数</el-col>
        <el-col :span="2">风险数</el-col>
        <el-col :span="6">分系统名称</el-col>
        <el-col :span="8">分系统地址</el-col>
        <el-col :span="3">系统风险指数</el-col>
        <el-col :span="3">系统状态</el-col>
      </el-row>
      <div v-if="labelInfo.list.length !== 0">
        <el-row
        class="state-item"
        justify="center"
        v-for="(item, index) in labelInfo.list"
        :key="index"
        v-show="index < 3 || isOpen"
      >
        <el-col :span="2">
          <span class="state-item__span">{{ item.weaknessCnt }}</span>
        </el-col>
        <el-col :span="2">
          <span class="state-item__span">{{ item.riskCnt }}</span>
        </el-col>
        <el-col :span="6">
          <span class="state-item__span">{{ item.subsystemName }}</span>
        </el-col>
        <el-col :span="8">
          <span class="state-item__span">{{
            item.subsystemIp
          }}</span>
        </el-col>
        <el-col :span="3">
          <span
            class="status-item__top__wei"
            :class="
              'status-item__top__' + levelMap[item.riskExponent.riskLevel]
            "
          >
            <qz-icon :class="levelMap[item.riskExponent.riskLevel]"></qz-icon>
            <span>{{ item.riskExponent.count || 0 }}</span>
            <qz-icon
              v-if="item.riskExponent.exponentTrend !== 'mid'"
              :class="
                item.riskExponent.exponentTrend === 'up'
                  ? 'add-color icon-jiantou-hong'
                  : 'decrease-color icon-jiantou-lv'
              "
            ></qz-icon>
          </span>
        </el-col>
        <el-col :span="3">
          <div class="status-item__status">
            <span :class="'status-item__status__' + stateMapEn[item.state]">{{
              stateMap[item.state]
            }}</span>
          </div>
        </el-col>
      </el-row>
      </div>
      <el-row v-show="labelInfo.list.length <= 0" style="text-align: center">
        暂无数据
      </el-row>
    </div>
    <div class="overview-system-state__footer" v-if="labelInfo.list.length > 3">
      <div class="overview-system-state__footer__item">
        <div class="action-link" @click="handleOpen">
          <span>{{ !isOpen ? "展开" : "收起" }}</span>
          <qz-icon
            :class="!isOpen ? 'icon-arrow-down-copy' : 'icon-arrow-up'"
            style="font-size: 14px; padding-left: 5px"
          ></qz-icon>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isOpen: false,
      stateMap: {
        0: "异常",
        1: "正常",
      },
      stateMapEn: {
        0: "abnormal",
        1: "normal",
      },
      levelMap: {
        1: "icon-diwei",
        2: "icon-zhongwei",
        3: "icon-gaowei",
      },
      labelInfo: {
        title: "分系统状态",
        set: "设置",
        list: [
          {
            weaknessCnt: 66,
            riskCnt: 77,
            subsystemName: 'Kylin',
            subsystemIp: '192.168.1.102',
            riskExponent: {
              riskLevel: 1,
              count: 25,
              exponentTrend: 'up'
            },
            state: 0
          },
          {
            weaknessCnt: 66,
            riskCnt: 77,
            subsystemName: 'Kylin',
            subsystemIp: '192.168.1.102',
            riskExponent: {
              riskLevel: 2,
              count: 25,
              exponentTrend: 'down'
            },
            state: 1
          },
          {
            weaknessCnt: 66,
            riskCnt: 77,
            subsystemName: 'Kylin',
            subsystemIp: '192.168.1.102',
            riskExponent: {
              riskLevel: 3,
              count: 25,
              exponentTrend: 'up'
            },
            state: 1
          },
          {
            weaknessCnt: 66,
            riskCnt: 77,
            subsystemName: 'Kylin',
            subsystemIp: '192.168.1.102',
            riskExponent: {
              riskLevel: 1,
              count: 25,
              exponentTrend: 'up'
            },
            state: 0
          },
        ],
      },
    };
  },
  methods: {
    // 控制展开/收起
    handleOpen() {
      this.isOpen = !this.isOpen;
    },
  },
};
</script>

<style lang="less">
// flex样式
.flex(@justify-content,@align-items) {
  display: flex;
  align-items: @align-items;
  justify-content: @justify-content;
}
// 边框样式
.border-style() {
  background: #ffffff;
  border: 1px solid #ececee;
}
.overview-system-state {
  width: 100%;
  padding: 20px;
  .border-style();
  & .add-color {
    color: #ff2828;
  }
  & .decrease-color {
    color: #33c17e;
  }
  &__row {
    margin-bottom: 20px;
    .flex(space-between, center);
  }
  &__labels {
    border: 1px solid #e4e7ed;
    & .header {
      font-weight: 400;
      font-size: 14px;
      font-family: PingFangSC-Medium;
      color: #000000 !important;
    }
    & .state-item {
      &__span {
        cursor: pointer;
      }
    }
    .el-row {
      height: 42px;
      line-height: 42px;
      color: #666666;
      font-size: 14px;
      font-weight: 400;
      &:first-child {
        font-family: 400;
      }
      &:last-child {
        border-right: none;
      }
    }
    .el-col {
      height: 42px;
      line-height: 42px;
      border-bottom: 1px solid #e4e7ed;
      border-right: 1px solid #e4e7ed;
      align-items: center;
      text-align: center;
      &:last-child {
        border-right: none;
      }
    }
    & .status-item {
      &__top {
        position: relative;
        &__title {
          font-family: PingFangSC-Medium;
          font-size: 16px;
          color: #333333;
          font-weight: 500;
          cursor: pointer;
        }
        &__icon-gaowei {
          color: #f55959;
        }
        &__icon-zhongwei {
          color: #f9ad33;
        }
        &__icon-diwei {
          color: #e1ce38;
        }
        &__wei {
          cursor: pointer;
          & span {
            margin-left: 5px;
            color: #606266;
          }
        }
      }
      &__status {
        font-family: PingFangSC-Regular;
        font-size: 14px;
        color: #606266;
        font-weight: 400;
        &__normal {
          background: #95ce68;
        }
        &__abnormal {
          background: #f55959;
        }
        & span {
          display: inline-block;
          width: 38px;
          height: 17px;
          line-height: 17px;
          text-align: center;
          border-radius: 8px;
          font-family: PingFangSC-Medium;
          font-size: 12px;
          color: #ffffff;
          font-weight: 500;
          cursor: pointer;
        }
      }
      &__label {
        margin-top: 23px;
        height: 109px;
        background: #f8f9fd;
        padding: 20px;
        display: flex;
        flex-direction: column;
        justify-content: space-between;
        span {
          font-size: 16px;
          &:hover {
            color: #47a5e7;
            cursor: pointer;
          }
        }
      }
    }
  }
  &__footer {
    margin-top: 10px;
    text-align: center;
    align-items: center;
    &__item {
      width: 50px;
      margin: 0 auto;
    }
  }
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值