all files / src/tabs/ tabsHeader.vue

100% Statements 12/12
100% Branches 8/8
100% Functions 4/4
100% Lines 12/12
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83                                                                                                                                             
<template>
  <div :class="['am-tabs-header',{'vertical':direction=='vertical'}]" ref="tabsHead">
    <slot></slot>
    <div class="line" ref="line"></div>
    <div class="action-wrapper">
      <slot name="actions"></slot>
    </div>
  </div>
 
</template>
 
<script>
  export default {
    name: "amTabsHeader",
    inject: ["eventBus", "direction", "lineWidthOrHeight"],
    mounted() {
      this.eventBus &&
      this.eventBus.$on("update:selected", (name, vm) => {
        this.calculateLineStyle(vm);
      });
    },
    methods: {
      calculateLineStyle(vm) {
        // 当选中状态样式导致元素宽度变化时,会出现下划线的宽度与当前选中的tabItem宽度不一致
        this.$nextTick(() => {
          let {
            left: left1,
            top: top1
          } = this.$refs.tabsHead.getBoundingClientRect();
          let {
            width,
            left: left2,
            height,
            top: top2
          } = vm.$el.getBoundingClientRect();
          const lineWidth = this.lineWidthOrHeight ? +this.lineWidthOrHeight : width
          const lineHeight = this.lineWidthOrHeight ? +this.lineWidthOrHeight : height
          if (this.direction === "horizontal") {
            this.$refs.line.style.width = `${lineWidth}px`;
            this.$refs.line.style.left = `${left2 - left1 + (width - lineWidth) / 2}px`;
          } else {
            this.$refs.line.style.height = `${lineHeight}px`;
            this.$refs.line.style.top = `${top2 - top1 + (height - lineHeight) / 2}px`;
          }
        });
      }
    }
  };
</script>
 
<style lang="scss" scoped>
  .am-tabs-header {
    position: relative;
    display: flex;
    justify-content: flex-start;
    flex-shrink: 0;
    border-bottom: 1px solid #ddd;
    > .line {
      position: absolute;
      bottom: -1px;
      border-bottom: 2px solid #1890ff;
      box-sizing: border-box;
      transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
    }
    > .action-wrapper {
      margin-left: auto;
      display: flex;
      align-items: center;
      justify-content: center;
      padding: 0 1em;
    }
    &.vertical {
      flex-direction: column;
      border-right: 1px solid #ddd;
      border-bottom: none;
      > .line {
        right: -1px;
        border-right: 2px solid #1890ff;
      }
    }
  }
</style>