【无标题】一个横向的tab栏

效果
滚动后效果
1,需要设置内发光方向
2,内容部分左边边框需要根据点击标题产生相对应的缺口,所以用两个单独的div制作边框效果。
3,内发光效果在标题和内容框交界处会有明显的割裂效果,试过几个方式,最后用defore制作一个渐变盒子效果最好。
在这里插入图片描述
4,滚动条隐藏
5,根据点击标题计算两个边框的长度,注意我的样式都是通过vh和vw来确定的宽度,但是因为获取滚动scrollTop获取的是屏幕的px,所以需要单独计算,不用通过vh和vw 的计算公式进行处理

<template>
  <div class="matter">
    <div class="serve-left" ref="serve_left">
      <div
        :class="index == active ? 'serve-title active' : 'serve-title'"
        v-for="(item, index) in titleList"
        :key="index"
        @click="changeTitle(index, $event)"
      >
        {{ item.text }}
      </div>
    </div>
    <div class="serve-right">
      <!-- 左边边框需要动态缺口,用两个盒子做效果 -->
      <div class="right-top" ref="right_top"></div>
      <div class="right-bottom" ref="right_bottom"></div>
    </div>
  </div>
</template>

<script>
export default {
  props: {},
  data() {
    return {
      titleList: [
        { text: "蔬菜怎么种植1", id: 1 },
        { text: "蔬菜怎么种植2", id: 2 },
        { text: "蔬菜怎么种植3", id: 3 },
        { text: "蔬菜怎么种植4", id: 4 },
        { text: "蔬菜怎么种植5", id: 5 },
        { text: "蔬菜怎么种植5", id: 5 },
        { text: "蔬菜怎么种植5", id: 5 },
        { text: "蔬菜怎么种植5", id: 5 },
        { text: "蔬菜怎么种植5", id: 5 },
        { text: "蔬菜怎么种植5", id: 5 },
        { text: "蔬菜怎么种植5", id: 5 },
        { text: "蔬菜怎么种植5", id: 5 },
        { text: "蔬菜怎么种植5", id: 5 },
        { text: "蔬菜怎么种植5", id: 5 },
      ],
      active: 0,
    };
  },
  computed: {},
  created() {},
  mounted() {},
  watch: {
    // 监听选中
    active: {
      deep: true,
      handler(newval, oldval) {
        this.countHeight(newval);
        // console.log(topHeight, bottomHeight);
      },
    },
  },
  methods: {
    changeTitle(index, e) {
      this.active = index;
    },
    // 计算左边边框
    countHeight(newval) {
      // 计算上边框高度
      var topHeight = newval * 60;
      this.$refs.right_top.style.height =
        "calc((" +
        topHeight +
        " / 1280 * 100vh) - " +
        this.$refs.serve_left.scrollTop +
        "px)";
      // 计算下边框高度
      var bottomHeight = (newval + 1) * 60 - 10;
      this.$refs.right_bottom.style.height =
        "calc(((445 - " +
        bottomHeight +
        ") / 1280 * 100vh) + " +
        this.$refs.serve_left.scrollTop +
        "px)";
    },
  },
  components: {},
};
</script>

<style scoped lang='less'>
* {
  box-sizing: border-box;
}
.matter {
  height: calc(445 / 1280 * 100vh);
  width: calc(1600 / 2560 * 100vw);
  .serve-left {
    float: left;
    height: calc(445 / 1280 * 100vh);
    width: calc(800 / 2560 * 100vw);
    overflow: auto;
    &::-webkit-scrollbar {
      width: 0 !important;
    }
    &::-webkit-scrollbar {
      width: 0 !important;
      height: 0;
    }
    .serve-title {
      margin: calc(10 / 1280 * 100vh) 0;
      text-align: center;
      border: #1677b3 solid 1px;
      height: calc(50 / 1280 * 100vh);
      font-size: calc(30 / 1280 * 100vh);
      line-height: calc(50 / 1280 * 100vh);
      border-radius: 5px;
      box-shadow: 0 0 15px rgb(22, 119, 179) inset;
      color: #1677b3;
    }
    .active {
      border-right: 0px;
      border-radius: 5px 0 0 5px;
      box-shadow: inset 0px 15px 15px -15px rgb(22, 119, 179),
        inset 0px -15px 15px -15px rgb(22, 119, 179),
        inset 15px 0px 15px -15px rgb(22, 119, 179);
    }
  }
  .serve-right {
    float: left;
    position: relative;
    height: calc(445 / 1280 * 100vh);
    width: calc(800 / 2560 * 100vw);
    border: #1677b3 solid 1px;
    border-radius: 0 5px 5px 0;
    box-shadow: inset 0px 15px 15px -15px rgb(22, 119, 179),
      inset 0px -15px 15px -15px rgb(22, 119, 179),
      inset -15px 0px 15px -15px rgb(22, 119, 179);
    border-left: 0px;
    margin: calc(10 / 1280 * 100vh) 0;
    .right-top {
      position: absolute;
      top: 0;
      width: 20px;
      height: calc(0 / 1280 * 100vh);
      box-shadow: inset 15px 0px 15px -15px rgb(22, 119, 179);
      border-left: #1677b3 solid 1px;
      &::before {
        content: "";
        position: absolute;
        bottom: calc(-20 / 1280 * 100vh);
        left: -1px;
        width: 20px;
        height: calc(20 / 1280 * 100vh);
        background: linear-gradient(
          135deg,
          rgba(22, 119, 179, 1),
          rgba(22, 119, 179, 0.5) 10%,
          rgba(22, 119, 179, 0.1) 30%,
          rgba(22, 119, 179, 0) 30%
        );
      }
    }
    .right-bottom {
      position: absolute;
      bottom: 0;
      width: 20px;
      height: calc(445 / 1280 * 100vh);
      box-shadow: inset 15px 0px 15px -15px rgb(22, 119, 179);
      border-left: #1677b3 solid 1px;
      &::before {
        content: "";
        position: absolute;
        top: calc(-20 / 1280 * 100vh);
        left: -1px;
        width: 20px;
        height: calc(20 / 1280 * 100vh);
        background: linear-gradient(
          45deg,
          rgba(22, 119, 179, 1),
          rgba(22, 119, 179, 0.5) 10%,
          rgba(22, 119, 179, 0.1) 30%,
          rgba(22, 119, 179, 0) 40%
        );
      }
    }
    .right-center {
      position: absolute;
      top: calc(146 / 1280 * 100vh);
      width: 20px;
      height: calc(20 / 1280 * 100vh);
      background: linear-gradient(
        45deg,
        rgba(22, 119, 179, 1),
        rgba(22, 119, 179, 0.3) 10%,
        rgba(22, 119, 179, 0) 50%
      );
    }
  }
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值