vue封装箭头矩形步骤条

1,613 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

  因工作需要,element组件中的el-step组件的样式无法满足笔者的需求;而且并不是一个页面需要这个组件,所以只好手动封装一个步骤条组件。

1、需求样式

1、步骤条形状为矩形箭头形式;
2、文字上下左右居中位于步骤条内,无描述空间;
3、通过外部变量activeId步骤跳转;

2、思路

1、用ul、li作为基本标签,首先绘制矩形div容器;
2、使用border的属性绘制三角形;

  js代码使用v-for循环数组stepArrayli标签的宽度为百分比,通过变量计算:(100/步骤数组长度)%

  activeId作为关键key值判断是否在当前步骤;
这里使用了一个多层判断的三元表达式:activeId == index ? 'current' : activeId > index ? 'passed' : ''

1、判断是否在当前步骤,是则添加类current,否则进行第二次判断;
2、判断是否已经经过当前步骤,是则添加类passed,否则不添加类,则是按照默认样式;

3、代码

<template>
  <ul>
    <li
      v-for="(item, index) in stepArray"
      :key="index"
      :style="{ width: 100 / stepArray.length + '%' }"
      :class="activeId == index ? 'current' : activeId > index ? 'passed' : ''"
    >
      <samp class="less1 left"></samp>
      <div class="block">{{ item.title }}</div>
      <span class="less"></span>
    </li>
  </ul>
</template>

<script>
export default {
  props: {
    activeId: {
      type: Number,
      default: 0
    },
    stepArray: {
      type: Array,
      default: () => []
    },
  },
}
</script>

css样式

  对于步骤条来说,最重要的部分莫过于样式,为书写方便,这里使用scss写法,首先声明根属性方便切换颜色之类的,使用css3中的var函数和calc函数配合自定义的根属性。

css3函数扩展:
1、var()函数:用于插入自定义的属性值

(1)使用方式参考下面的写法:var(自定义属性)

2、calc()函数:用于动态计算属性值,

(1)必须是有长度得比如heightwidth
(2)支持 "+", "-", "*", "/" 运算;
(3)同时使用标准的数学运算优先级规则;
(4)使用方式:calc(100% - 20px)
(5)注意:写法必须严格格式化留下空格

<style lang="scss" scoped>
ul {
  list-style: none;
  --step-bg-color: #dadcde;
  --step-item-bg-color: #b5b9bd;
  --step-current-bg-color: #084dab;
  --step-passed-bg-color: #3971bc;
  --step-height: 45px;
  --step-arrow-height: calc(var(--step-height) / 2);
  height: var(--step-height);
  width: 100%;
  background: var(--step-bg-color);
  padding: 0 20px;
  box-sizing: border-box;
  li {
    background: var(--step-bg-color);
    display: inline-block;
    position: relative;
    margin-left: -5px;
    // cursor: pointer;
    &:first-of-type{
      margin-left: 10px;
    }
    .less {
      border-style: dashed dashed dashed solid;
      border-color: transparent transparent transparent
        var(--step-item-bg-color);
      border-width: var(--step-arrow-height) 0
        var(--step-arrow-height) calc(var(--step-arrow-height) / 2);
      top: 0;
    } /*dashed 设置透明*/
    .less1 {
      border-style: dashed dashed dashed solid;
      border-color: transparent transparent transparent var(--step-bg-color);
      border-width: var(--step-arrow-height) 0
        var(--step-arrow-height) calc(var(--step-arrow-height) / 2);
      top: 0;
    }
    .left {
      left: 0;
    }
    samp {
      display: block;
      position: absolute;
      z-index: 2;
    }
    span {
      display: block;
      position: relative;
      float: left;
      z-index: 3;
    }
    .block {
      width: calc(100% - 15px);
      line-height: var(--step-height);
      text-align: center;
      background: var(--step-item-bg-color);
      vertical-align: middle;
      color: #fff;
      float: left;
      z-index: 1;
    }
  }
  .current{
    .block {
      background: var(--step-current-bg-color);
    }
    .less {
      border-color: transparent transparent transparent var(--step-current-bg-color);
    } 
  }
  .passed{
    .block {
      background: var(--step-passed-bg-color);
    }
    .less {
      border-color: transparent transparent transparent var(--step-passed-bg-color);
    } 
  }
}
</style>

效果图

image.png