div+css 蛇形布局/S形布局

1,452 阅读1分钟

设计图: 要求做一个流程S形顺序执行过程,完成流程高亮

image.png

实现思路:

  1. 先将一维数组按5个一组改成二维数组(数组处理就贴图,一看就懂) image.png
  2. flex布局,奇偶行用不同的类名控制 image.png

template代码:

<div class="flow-panel">
    <div v-for="(item, index) in dealList" :key="index" :class="(index + 1) % 2 === 1 ? 'list-li' : 'reverse-li'">
      <!-- row-first-node 每行第一个的线要处理 -->
      <div
        v-for="(node, idx) in item"
        :key="idx"
        class="node"
        :class="{
          'row-first-node': idx === 0,
          finished: node.status === 1
        }"
      >
        <!-- 线 -->
        <div class="line"></div>
        <!-- 向下转折线--矩形 每行的第一个,除了首行 -->
        <div v-if="index !== 0 && idx === 0" class="rectangle-line"></div>
        <!-- 节点 -->
        <div class="node-item">
          <i class="point"></i>
          <p class="text">{{ node.text }}</p>
          <p class="time">{{ node.time || '---' }}</p>
        </div>
      </div>
    </div>
  </div>

SCSS样式代码

<style lang="scss" scoped>
$height: 130px; //节点的高
.flow-panel {
  padding: 40px 5%;
  //  连接线 用absolute top0
  .line {
    height: 2px;
    background: #343c59; //灰色
    position: absolute;
    width: 100%;
    top: 0;
    z-index: 0;
  }
  //  左右往下画的连线 用的矩形,三边 用absolute top0
  .rectangle-line {
    position: absolute;
    width: 50%;
    border-color: #343c59;
    border-style: solid;
    border-width: 0;
    border-top-width: 2px;
    border-bottom-width: 2px;
    bottom: calc(100% - 2px);
    height: calc($height - 2px);
  }
  //点的样式
  .point {
    width: 12px;
    height: 12px;
    z-index: 100;
    border-radius: 50%;
    background: #7e89a4;
    border: 2px solid #171c3c;
    display: block;
    margin: 0 auto 10px auto;
  }
  //节点样式
  .node {
    width: 20%;
    text-align: center;
    position: relative;
    height: $height;

    .node-item {
      position: absolute;
      width: 100%;
      top: -7px; //点需要向上偏移7px才在线上
      text-align: center;
      z-index: 10;
      p.text {
        font-size: 16px;
        color: #fff;
      }
    }
  }
  //正向排列
  .list-li {
    display: flex;
    justify-content: start;
    //左侧转折线 左对齐
    .rectangle-line {
      left: 0;
      border-left-width: 2px;
    }
    //排列,线方向从左到右
    .line {
      left: -50%;
    }
    //正向 第一个节点 不要线(因为到它的点是用的 rectangle-line 折线)
    .row-first-node .line {
      width: 0%;
    }
  }

  //反向排列
  .reverse-li {
    display: flex;
    justify-content: space-between;
    flex-direction: row-reverse;
    justify-content: end;
    //右侧转折线 右对齐
    .rectangle-line {
      right: 0;
      border-right-width: 2px;
    }
    //反向排列,线方向从右到左
    .line {
      right: -50%;
    }
    //反向 第一个节点 不要线(因为到它的点是用的 rectangle-line 折线)
    .row-first-node .line {
      width: 0%;
    }
  }

  //设置已完成节点的线,和点的颜色
  .finished {
    .line {
      background: #2d5afa;
    }
    .rectangle-line {
      border-color: #2d5afa;
    }
    .point {
      background: #2d5afa;
      border: 2px solid #fff;
    }
  }
}

</style>

注意 maxLen 变更时, css里 node的宽也要相对应的调整