index.vue 3.94 KB
Newer Older
Nature's avatar
Nature committed
1
<template>
JingChao's avatar
JingChao committed
2
  <section :class="[cusClass,overFlow]" class="hls-switch-tab" >
Nature's avatar
Nature committed
3 4 5
    <section :style="transform" class="tab-content">
      <slot/>
    </section>
Nature's avatar
Nature committed
6 7 8
  </section>
</template>
<script>
Nature's avatar
Nature committed
9
import { base } from '../../common/mixins'
Nature's avatar
Nature committed
10 11 12
import stabItem from './tab-item'

export default {
JingChao's avatar
JingChao committed
13
  name: 'STab',
Nature's avatar
Nature committed
14
  mixins: [base],
Nature's avatar
Nature committed
15
  component: { stabItem },
Nature's avatar
Nature committed
16
  props: {
JingChao's avatar
JingChao committed
17 18 19 20
    value: {
      type: Number,
      default: 0,
    },
Nature's avatar
Nature committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
    position: {
      type: String,
      default: 'top',
    },
    cusClass: {
      type: String,
      default: '',
    },
    defaultActive: {
      type: Number,
      default: 0,
    },
    showDivider: {
      type: Boolean,
      default: false,
    },
Nature's avatar
Nature committed
37 38
    overflowX: {
      type: Boolean,
Nature's avatar
Nature committed
39
      default: true,
Nature's avatar
Nature committed
40
    },
Nature's avatar
Nature committed
41 42 43 44
    hasBorder: {
      type: Boolean,
      default: false,
    },
Nature's avatar
Nature committed
45 46 47 48 49 50
  },
  data () {
    return {
      items: [],
      length: '',
      activedIndex: '',
Nature's avatar
Nature committed
51
      translate: 0,
Nature's avatar
Nature committed
52 53 54
    }
  },
  computed: {
Nature's avatar
Nature committed
55 56 57
    overFlow () {
      return this.overflowX ? 'auto-overflow-x' : ''
    },
Nature's avatar
Nature committed
58 59
    count () {
      this.length = this.items.length
Nature's avatar
Nature committed
60
      return this.length
Nature's avatar
Nature committed
61 62 63 64 65 66 67 68 69 70 71
    },
    current () {
      let vm = this
      let length = (vm.items.length) - 1
      if (vm.defaultActive > length) {
        vm.index = length
      } else {
        vm.index = vm.defaultActive
      }
      return vm.index
    },
Nature's avatar
Nature committed
72 73 74 75

    transform () {
      return {
        transform: 'translateX(' + this.translate + 'px' + ')',
Nature's avatar
Nature committed
76
        // transition: 'right 0.3s cubic-bezier(0.35, 0, 0.25, 1), left 0.3s cubic-bezier(0.35, 0, 0.25, 1) 0.09s;',
Nature's avatar
Nature committed
77 78
      }
    },
Nature's avatar
Nature committed
79
  },
JingChao's avatar
JingChao committed
80 81 82 83 84 85 86 87 88 89
  watch: {
    value (value) {
      if (value > this.count - 1) {
        throw 'tab index out of bound exception'
      } else {
        this.defaultActive === value
        this.setTabActive(value)
      }
    },
  },
Nature's avatar
Nature committed
90 91
  mounted () {
    let vm = this
JingChao's avatar
JingChao committed
92 93 94 95 96
    if (vm.value > vm.count - 1) {
      throw 'tab index out of bound exception'
    } else {
      vm.setTabActive(vm.value)
    }
Nature's avatar
Nature committed
97 98
  },
  methods: {
99 100 101 102 103 104 105 106 107 108 109
    setTabActive (index) {
      let vm = this
      vm.items.forEach(item => {
        item.$el.classList.remove('activated')
      })
      setTimeout(() => {
        this.items[index].$el.classList.add('activated')
      }, 100)
      let width = this.items[index].$el.clientWidth
      this.actived(index, width)
    },
Nature's avatar
Nature committed
110
    actived (index, clientWidth) {
Nature's avatar
Nature committed
111 112
      this.activedIndex = index
      this.$emit('tabClick', index)
JingChao's avatar
JingChao committed
113
      this.$emit('input', index)
Nature's avatar
Nature committed
114 115 116 117 118

      this.scrollToActiveTab(index, clientWidth)
    },

    scrollToActiveTab (index, width) {
Nature's avatar
Nature committed
119
      let clientWidth = this.$el.clientWidth
Nature's avatar
Nature committed
120 121
      index += 1
      let vm = this
Nature's avatar
Nature committed
122 123
      let count = Math.floor(clientWidth / width)
      let overFlowWidth = clientWidth - count * width
Nature's avatar
Nature committed
124 125 126
      let num
      if (index > count) {
        num = index - count
Nature's avatar
Nature committed
127 128 129
        if ((vm.count - index) >= 1) {
          num += 1
        }
Nature's avatar
Nature committed
130 131 132 133
      } else {
        num = 0
      }
      if (num === 0) {
Nature's avatar
Nature committed
134
        vm.translate = 0
Nature's avatar
Nature committed
135
      } else {
Nature's avatar
Nature committed
136
        vm.translate = -num * width + overFlowWidth
Nature's avatar
Nature committed
137
      }
Nature's avatar
Nature committed
138 139 140 141 142 143
    },
  },
}
</script>

<style lang="less">
Nature's avatar
Nature committed
144 145 146 147
  .auto-overflow-x {
    overflow-x: auto;
  }

Nature's avatar
Nature committed
148 149
  .hls-switch-tab {
    width: 100%;
Nature's avatar
Nature committed
150
    position: relative;
Nature's avatar
Nature committed
151 152
    z-index: 1;
    display: flex;
Nature's avatar
Nature committed
153
    // justify-content: space-around;
Nature's avatar
Nature committed
154 155
    height: 40px;
    background-color: #fff;
Nature's avatar
Nature committed
156

Nature's avatar
Nature committed
157
    &-top {
Nature's avatar
Nature committed
158
     // top: 0;
Nature's avatar
Nature committed
159

Nature's avatar
Nature committed
160 161 162 163
      &:after {
        .setBottomLine();
      }
    }
Nature's avatar
Nature committed
164

Nature's avatar
Nature committed
165
    &-bottom {
Nature's avatar
Nature committed
166
     // bottom: 0;
Nature's avatar
Nature committed
167

Nature's avatar
Nature committed
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200
      &:before {
        .setTopLine();
      }
    }

    .setTopLine(@c: rgba(0,0,0,.1)) {
      content: " ";
      position: absolute;
      left: 0;
      top: 0;
      right: 0;
      height: 1px;
      border-top: 1px solid @c; /*no*/
      color: @c;
      transform-origin: 0 0;
      transform: scaleY(0.5);
    }

    .setBottomLine(@c: rgba(0,0,0,.1)) {
      content: " ";
      position: absolute;
      left: 0;
      bottom: 0;
      right: 0;
      height: 1px;
      border-bottom: 1px solid @c; /*no*/
      color: @c;
      transform-origin: 0 100%;
      transform: scaleY(0.5);
    }
  }

</style>