<template>
  <div class="x-tab" :class="{'x-tab--fixed': fixed}">
    <div class="x-tab__list">
      <slot></slot>
    </div>
    <div
      v-if="!hideBar"
      :class="{
        'x-tab-ink-bar': true,
        'x-tab-ink-bar-transition-forward': direction === 'forward',
        'x-tab-ink-bar-transition-backward': direction === 'backward'
      }"
      :style="{left: barLeft, right: barRight}"></div>
  </div>
</template>

<script>
export default {
  props: {
    value: String,
    hideBar: {
      type: Boolean,
      default: false
    },
    fixed: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      selecedIndex: -1,
      direction: 'forward'
    }
  },
  mounted() {
    // 说明：为什么不用计算属性的方式确保 selecedIndex 值与 value 同步
    //
    // selecedIndex 除了依赖 value，还需要查询 this.$children 才能得到准确的结果
    // 而 this.$children 非响应式数据（变更后不会触发计算属性更新），且
    // 初始化阶段尚没有初始化 this.$children，也就是说：
    // - selecedIndex 依赖的 this.$children 在组件创建时没有数据，所以值不可用
    // - 组件创建后 this.$children 有数据，但不能通知 selectedIndex 重新计算
    // 所以，需要手动触发更新，除了监听 value 变更的地方，mounted 触发时也要执行
    // 更新，确保初始的 selecedIndex 值准确
    //
    // 当然，这是比较笨的办法，如果能够在使用计算属性的情况下，还可以在初次获取到
    // this.$children 后及时进行更新，会是更好的办法。后续有新的方案再改进！
    this.updateSelectedIndex()
  },
  watch: {
    value(newVal, oldVal) {
      const oldIndex = this.getChildIndex(oldVal)
      const newIndex = this.getChildIndex(newVal)
      this.direction = oldIndex > newIndex ? 'backward' : 'forward'
      this.updateSelectedIndex()
    }
  },
  computed: {
    barLeft() {
      if (this.selecedIndex === -1) return 0
      return `${this.selecedIndex * 100 / this.$children.length}%`
    },
    barRight() {
      if (this.selecedIndex === -1) return '100%'
      return `${(this.$children.length - this.selecedIndex - 1) * 100 / this.$children.length}%`
    }
  },
  methods: {
    updateSelectedIndex() {
      this.selecedIndex = this.getChildIndex(this.value)
    },
    getChildIndex(id) {
      for (let i = 0, len = this.$children.length; i < len; i++) {
        if (this.$children[i].id === id) return i
      }
      return -1
    }
  }
}
</script>

<style lang="less">
.x-tab {
  position: relative;

  &--fixed {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 9;
  }

  &__list {
    position: relative;
    display: flex;
    background-color: #fff;
    border-bottom: 1px solid #e5e5e5;
  }

  &-ink-bar {
    position: absolute;
    height: 2px;
    bottom: 0;
    left: 0;
    right: 100%; // 初始宽度为 0，不可见
    text-align: center;
    background: #EA5341;
  }

  &-ink-bar-transition-forward {
    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;
  }

  &-ink-bar-transition-backward {
    transition: right 0.3s cubic-bezier(0.35, 0, 0.25, 1) 0.09s, left 0.3s cubic-bezier(0.35, 0, 0.25, 1);
  }
}
</style>
