实现波浪形特殊Tab

1,911 阅读2分钟

步骤一:HTML显示

  1. 循环输出 tabList 变量中Tab标签的数据。
  2. 点击时把Tab数据中的 key 保存到 tabIndex 中,作为判断当前点击了哪一项。
  3. 动态class类,使用“三元表达式”判断奇/偶项,从而给出对应的类。
  4. 动态style样式,使用“三元表达式”判断当前项的 keytabIndex 是否相等,相等表示当前点击了该项,给出对应的颜色。
<div class="box">
    <div
       v-for="(item, index) in tabList"
       :key="item.key"
       @click="tabIndex = item.key"
       :class="['item', index / 0 ? 'item-even' : 'item-odd']"
       :style="{
         '--evenColor': item.key === tabIndex ? '#edf4fa' : '#fff',
          '--oddColor': item.key === tabIndex ? '#edf4fa' : '#fff',
        }"
     >
        <span> {{ item.label }}</span>
     </div>
</div>

步骤二:定义数据

  1. 定义 tabList 变量是Tab标签的数据。
  2. 定义 tabIndex 是作为判断当前点击了哪一项。
<script lang="ts" setup>
    import { ref } from "vue";
    const tabList = [
      {
        key: 0,
        label: "应用领域",
      },
      {
        key: 1,
        label: "应用专题",
      },
    ];
    const tabIndex = ref<number>(0);
</script>

步骤三:设置样式 (重点)

  1. 使用 border-radius 制作弧度的一角

Snipaste_2024-05-15_14-27-45.png

.item-odd {
    background-color: var(--oddColor);  //动态颜色
    border-radius: 0 15px 0 0;
}
  1. 使用 ::before 伪类制作特殊的尖尖

Snipaste_2024-05-15_14-29-26.png

.item-odd::before {
    background: radial-gradient(
      circle at 100% 0,
      transparent,
      transparent 20px,
      red 10px
    );
    bottom: 0;
    right: -20px;
}
  1. 使用 transform: skew(-20deg) 倾斜div,制作波浪的弧度

Snipaste_2024-05-15_14-33-35.png

.item {
   transform: skew(20deg);
}
  1. 使用 ::after 伪类制作长方体,挡住倾斜的一边

Snipaste_2024-05-15_14-36-00.png

.item-odd::after {
    content: "";
    position: absolute;
    width: 20px;
    height: 100%;
    background-color: var(--oddColor);  //动态颜色
    left: -10px;
    top: 0;
    transform: skew(-20deg);
}
  1. 使用 overflow: hidden; 隐藏超出的
完整的style代码
<style lang="scss" scoped>
  .box {
      display: flex;
      border: 1px solid black;
      margin-top: 10px;
      overflow: hidden;
      .item span {
        display: block;
        transform: skew(-20deg);
        height: 100%;
        text-align: center;
        line-height: 50px;
      }
      .item {
        flex: 1;
        height: 50px;
        position: relative;
        transform: skew(20deg);
      }
      .item::before {
        content: "";
        position: absolute;
        width: 20px;
        height: 20px;
      }

      // 奇数
      .item-odd {
        background-color: var(--oddColor);
        border-radius: 0 15px 0 0;
      }
      //右边弧形三角
      .item-odd::before {
        background: radial-gradient(
          circle at 100% 0,
          transparent,
          transparent 20px,
          var(--oddColor) 10px
        );
        bottom: 0;
        right: -20px;
      }
      //左边的方块
      .item-odd::after {
        content: "";
        position: absolute;
        width: 20px;
        height: 100%;
        background-color: var(--oddColor);
        left: -10px;
        top: 0;
        transform: skew(-20deg);
      }
      
      // 偶数
      .item-even {
        background-color: var(--evenColor);
        border-radius: 0 0 0 15px;
      }
      //左边弧形三角
      .item-even::before {
        background: radial-gradient(
          circle at 0 100%,
          transparent,
          transparent 20px,
          var(--evenColor) 20px
        );
        top: 0;
        left: -20px;
      }
      //右边的方块
      .item-even::after {
        content: "";
        position: absolute;
        width: 20px;
        height: 100%;
        background-color: var(--evenColor);
        right: -10px;
        top: 0;
        transform: skew(-20deg);
      }
    }
</style>

Snipaste_2024-05-15_14-40-28.png

Snipaste_2024-05-15_14-40-58.png

注意:左右两个tab的 style 样式是不一样的,他们的弧度是相反的!

本人是个初学小白,如果代码有不规范或者可以更优化的地方,麻烦各位jym能指出,让我多多学习,希望大家包含,谢谢。