使用Element-UI的步骤条和进度条实现二级步骤条

实现效果在这里插入图片描述

在这里插入图片描述

实现步骤

1.完成初步样式

在这里插入图片描述
将6个部分共同组成一个二级进度条,分别设置样式,用display:flex完成布局
html部分:

<div class="step">
      <!-- 第一部分 -->
      <div class="dot blue"></div> 
      <div class="step_mod">
        <!-- 第二部分 -->
        <div class="bar blue"></div>
        <!-- 第三部分 -->
        <div class="process">
          <div class="progressCircle">
            <el-progress type="circle" :stroke-width="15" :percentage="50" :show-text="false"></el-progress>
            <div class="progressText">一级</div>
          </div>
          <div class="process_title">二级</div>
        </div>
        <!-- 第四部分 -->
        <div class="bar"></div>
        <!-- 第五部分 -->
        <div class="wait">未进行</div>
      </div>
      <div class="bar"></div>
      <!-- 第六部分 -->
      <div class="dot"></div>
    </div>

css部分:

.step {
  width: auto;
  margin: 40px auto;
  display: flex;
  justify-content: center;
  align-items: center;
  .dot {
    width: 12px;
    height: 12px;
    border-radius: 6px;
    background: #c3c3c3;
  }
  .step_mod {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .process {
    width: 50px;
    height: 50px;
    .process_title {
      text-align: center;
      font-size: 12px;
      color: #0290ff;
      line-height: 20px;
      margin-top: 20px;
      white-space: nowrap;
    }
    /deep/.el-progress-circle {
      width: 50px !important;
      height: 50px !important;
    }
    /deep/.el-progress__text {
      font-size: 14px !important;
      line-height: 20px;
    }
  }
  .progressText {
    text-align: center;
    margin-top: -40px;
    font-size: 14px;
  }
  .wait {
    font-size: 14px;
    color: #ffffff;
    line-height: 20px;
    background: #c3c3c3;
    width: 50px;
    height: 50px;
    border-radius: 25px;
    text-align: center;
    padding: 15px 0;
    box-sizing: border-box;
  }
  .bar {
    width: 82px;
    height: 4px;
    background: #f5f5f5;
  }
  .blue {
    background: #0290ff;
  }
}
2.填充数据

在这里插入图片描述

<!-- stageTree:记录环节信息的树;
     progressFlag:判断当前环节是否已完成,或正在进行;
     secondValue:计算得到的进度百分比;
     label:一级环节名称
     secondLabel:当前二级环节名称-->
     
    <div class="step">
      <div class="dot blue"></div>
      <div class="step_mod" v-for="(item,index) in stageTree" :key="index">
        <div v-if="item.progressFlag" class="bar blue"></div>
        <div v-if="item.progressFlag" class="process">
          <div class="progressCircle">
            <el-progress
              type="circle"
              :stroke-width="15"
              :percentage="item.secondValue"
              :show-text="false"
            ></el-progress>
            <div class="progressText">{{item.label}}</div>
          </div>
          <div v-if="index===firstIndex" class="process_title">{{secondLabel}}</div>
        </div>
        <div v-if="!item.progressFlag" class="bar"></div>
        <div v-if="!item.progressFlag" class="wait">{{item.label}}</div>
      </div>
      <div class="bar"></div>
      <div class="dot"></div>
    </div>
data部分:
data() {
    return {
      //节点信息
      stageTree: [
        {
          label: "一级 1",
          progressFlag: false,
          secondValue: 0,
          children: [
            {
              label: "二级 1-1"
            }
          ]
        },
        {
          label: "一级 2",
          progressFlag: false,
          secondValue: 0,
          children: [
            {
              label: "二级 2-1"
            },
            {
              label: "二级 2-2"
            }
          ]
        },
        {
          label: "一级 3",
          progressFlag: false,
          secondValue: 0,
          children: [
            {
              label: "二级 3-1"
            },
            {
              label: "二级 3-2"
            },
            {
              label: "二级 3-3"
            }
          ]
        },
        {
          label: "一级 4",
          progressFlag: false,
          secondValue: 0,
          children: [
            {
              label: "二级 4-1"
            },
            {
              label: "二级 4-2"
            },
            {
              label: "二级 4-3"
            },
            {
              label: "二级 4-4"
            }
          ]
        }
      ],
      firstLabel: "",//一级环节名称
      firstIndex: -1,//一级环节序号
      secondLine: [],//当前一级环节所对应的二级环节列表
      secondLabel: "",//二级环节名称
      secondIndex: 0//二级环节序号
    };
  },

源码

  • 这里我为了方便方便调试,添加了环节设置的功能,完整代码如下:
<template>
  <div>
    <div>二级进度条</div>
    <!-- stageTree:记录环节信息的树;
     progressFlag:判断当前环节是否已完成,或正在进行;
     secondValue:计算得到的进度百分比;
     label:一级环节名称
     secondLabel:当前二级环节名称-->
    <div class="step">
      <div class="dot blue"></div>
      <div class="step_mod" v-for="(item,index) in stageTree" :key="index">
        <div v-if="item.progressFlag" class="bar blue"></div>
        <div v-if="item.progressFlag" class="process">
          <div class="progressCircle">
            <el-progress
              type="circle"
              :stroke-width="15"
              :percentage="item.secondValue"
              :show-text="false"
            ></el-progress>
            <div class="progressText">{{item.label}}</div>
          </div>
          <div v-if="index===firstIndex" class="process_title">{{secondLabel}}</div>
        </div>
        <div v-if="!item.progressFlag" class="bar"></div>
        <div v-if="!item.progressFlag" class="wait">{{item.label}}</div>
      </div>
      <div class="bar"></div>
      <div class="dot"></div>
    </div>
    <div class="testBox">
      <div>环节设置:</div>
      <div class="flex_box">
        <div class="processLine">
          一级环节:
          <i class="el-icon-circle-plus-outline" @click="addNode(1)"></i>
          <div class="node" v-for="(item,index) in stageTree" :key="index">
            <el-input v-model="item.label" placeholder="请输入环节名称" @focus="focusOnfirst(item,index)"></el-input>
            <i class="el-icon-remove-outline" @click="deleteNode(1,index)"></i>
          </div>
        </div>
        <div class="processLine">
          {{firstLabel}}的二级环节:
          <i class="el-icon-circle-plus-outline" @click="addNode(2)"></i>
          <div class="node" v-for="(item,index) in secondLine" :key="index">
            <el-input v-model="item.label" placeholder="请输入环节名称" @focus="focusOnsecond(item,index)"></el-input>
            <i class="el-icon-remove-outline" @click="deleteNode(2,index)"></i>
          </div>
        </div>
        <!-- 箭头控制进度 -->
        <div class="processLine">
          <i class="el-icon-right btn" @click="next()"></i>
          <i class="el-icon-back btn" @click="back()"></i>
        </div>
      </div>
      <div>使用说明:</div>
      <div>点击一级环节展开二级环节;</div>
      <div>点击二级环节设置当前环节</div>
    </div>
  </div>
</template>
<script>
export default {
  name: "Step",
  props: {},
  data() {
    return {
      //节点信息
      stageTree: [
        {
          label: "一级 1",
          progressFlag: false,
          secondValue: 0,
          children: [
            {
              label: "二级 1-1"
            }
          ]
        },
        {
          label: "一级 2",
          progressFlag: false,
          secondValue: 0,
          children: [
            {
              label: "二级 2-1"
            },
            {
              label: "二级 2-2"
            }
          ]
        },
        {
          label: "一级 3",
          progressFlag: false,
          secondValue: 0,
          children: [
            {
              label: "二级 3-1"
            },
            {
              label: "二级 3-2"
            },
            {
              label: "二级 3-3"
            }
          ]
        },
        {
          label: "一级 4",
          progressFlag: false,
          secondValue: 0,
          children: [
            {
              label: "二级 4-1"
            },
            {
              label: "二级 4-2"
            },
            {
              label: "二级 4-3"
            },
            {
              label: "二级 4-4"
            }
          ]
        }
      ],
      firstLabel: "",//一级环节名称
      firstIndex: -1,//一级环节序号
      secondLine: [],//当前一级环节所对应的二级环节列表
      secondLabel: "",//二级环节名称
      secondIndex: 0//二级环节序号
    };
  },
  methods: {
    //点击一级节点
    focusOnfirst(item, index) {
      this.firstIndex = index;
      this.firstLabel = item.label;
      this.secondLine = item.children;
    },
    //点击二级节点
    focusOnsecond(item, index) {
      this.secondLabel = item.label;
      this.stageTree.forEach((ele, No) => {
        ele.progressFlag = false;
        ele.secondValue = 0;
      });
      for (let i = 0; i < this.stageTree.length; i++) {
        this.stageTree[i].progressFlag = true;
        if (i === this.firstIndex) {
          this.stageTree[i].secondValue =
            ((index + 1) * 100) / this.secondLine.length;
          break;
        } else {
          this.stageTree[i].secondValue = 100;
        }
      }
    },
    //增加节点
    addNode(level) {
      if (level === 1) {
        this.stageTree.push({
          label: "",
          progressFlag: false,
          secondValue: 0,
          children: []
        });
      } else {
        this.secondLine.push({ label: "" });
      }
    },
    //删除节点
    deleteNode(level, index) {
      if (level === 1) {
        this.stageTree.splice(index, 1);
      } else {
        this.secondLine.splice(index, 1);
      }
    },
    //回退
    back() {
      this.secondIndex--;
      if (this.secondIndex === -1) {
        if (this.firstIndex === 0) {
          this.firstIndex--;
          this.secondIndex = 0;
          this.stageTree[0].progressFlag = false;
          this.stageTree[0].secondValue = 0;

          return;
        } else if (this.firstIndex === -1) {
          console.log(this.stageProgress);
          this.secondIndex = 0;
          return;
        } else {
          this.firstIndex--;
          this.firstLabel = this.stageTree[this.firstIndex].label;
          this.secondIndex =
            this.stageTree[this.firstIndex].children.length - 1;
          this.secondLine = this.stageTree[this.firstIndex].children;
          this.secondLabel = this.secondLine[this.secondIndex].label;
        }
      } else {
        this.secondLine = this.stageTree[this.firstIndex].children;
        this.secondLabel = this.secondLine[this.secondIndex].label;
      }
      console.log(this.secondLabel);
      this.stageTree.forEach((ele, No) => {
        ele.progressFlag = false;
        ele.secondValue = 0;
      });
      for (let i = 0; i < this.stageTree.length; i++) {
        this.stageTree[i].progressFlag = true;
        if (i === this.firstIndex) {
          this.stageTree[i].secondValue =
            ((this.secondIndex + 1) * 100) / this.secondLine.length;
          break;
        } else {
          this.stageTree[i].secondValue = 100;
        }
      }
    },
    //前进
    next() {
      this.secondIndex++;
      if (
        this.firstIndex == -1 ||
        this.secondIndex == this.stageTree[this.firstIndex].children.length
      ) {
        this.firstIndex++;
        this.firstLabel = this.stageTree[this.firstIndex].label;
        this.secondIndex = 0;
        this.secondLine = this.stageTree[this.firstIndex].children;
        this.secondLabel = this.secondLine[this.secondIndex].label;
      } else {
        this.secondLine = this.stageTree[this.firstIndex].children;
        this.secondLabel = this.secondLine[this.secondIndex].label;
      }
      this.stageTree.forEach((ele, No) => {
        ele.progressFlag = false;
        ele.secondValue = 0;
      });
      for (let i = 0; i < this.stageTree.length; i++) {
        this.stageTree[i].progressFlag = true;
        if (i === this.firstIndex) {
          this.stageTree[i].secondValue =
            ((this.secondIndex + 1) * 100) / this.secondLine.length;
          break;
        } else {
          this.stageTree[i].secondValue = 100;
        }
      }
    }
  }
};
</script>
<style lang="less" scoped>
.step {
  width: auto;
  margin: 40px auto;
  display: flex;
  justify-content: center;
  align-items: center;
  .dot {
    width: 12px;
    height: 12px;
    border-radius: 6px;
    background: #c3c3c3;
  }
  .step_mod {
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .process {
    width: 50px;
    height: 50px;
    .process_title {
      text-align: center;
      font-size: 12px;
      color: #0290ff;
      line-height: 20px;
      margin-top: 20px;
      white-space: nowrap;
    }
    /deep/.el-progress-circle {
      width: 50px !important;
      height: 50px !important;
    }
    /deep/.el-progress__text {
      font-size: 14px !important;
      line-height: 20px;
    }
  }
  .progressText {
    text-align: center;
    margin-top: -40px;
    font-size: 14px;
  }
  .wait {
    font-size: 14px;
    color: #ffffff;
    line-height: 20px;
    background: #c3c3c3;
    width: 50px;
    height: 50px;
    border-radius: 25px;
    text-align: center;
    padding: 15px 0;
    box-sizing: border-box;
  }
  .bar {
    width: 82px;
    height: 4px;
    background: #f5f5f5;
  }
  .blue {
    background: #0290ff;
  }
}
.testBox {
  text-align: left;
  .flex_box {
    display: flex;
    .processLine {
      margin: 20px;
      i {
        cursor: pointer;
        float: right;
      }
      .btn {
        font-size: 80px;
        margin: 50px;
      }
      .node {
        margin: 10px 0;
        display: flex;
        align-items: baseline;
      }
    }
  }
}
</style>

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值