搜索组件_能搜索的 tabHead 组件

adf43668eed1a448841480aef2665492.png

d10cc45bb277e3f835ccb278337e3bda.png
<template>
  <div class="outer-wrap" ref="outerWrap">
    <div class="fy-tab-head-wrap" ref="tabHead">
      <ul class="tab-title-list" ref="tabUl">
        <li
          :key="index"
          @click.stop.prevent="selectTab(item, index)"
          v-for="(item, index) in tabTitleList"
        >
          <span :class="[curIndex == index ? 'active' : '']" class="tab-item">{{item}}</span>
        </li>
        <transition name="fade">
          <i @click.stop.prevent="clickSearchIcon" class="search-icon" v-show="isSearch"></i>
        </transition>
        <transition name="fade">
          <div @click.stop class="search" v-show="showSearchIput">
            <i class="icon"></i>
            <fy-input
              :autofocus="true"
              @click.stop.prevent.native
              @keyup.enter.native.stop.prevent="enterSearch"
              class="fyinput"
              placeholder="请输入关键字"
              v-model="searchInput"
            ></fy-input>
          </div>
        </transition>
      </ul>
    </div>
    <div
      :style="{'height': $refs.tabHead.getBoundingClientRect().height + 'px', 'width': $refs.tabHead.getBoundingClientRect().width + 'px'}"
      class="sticky--holder"
      v-if="showStickyHolder"
    ></div>
  </div>
</template>

<script>
export default {
  name: 'fyTabHead',
  props: {
    tabTitleList: {
      type: Array,
      required: true,
    },
    defaultCurIndex: {
      type: [Number, String],
      default: 0,
    },
    labelKey: {
      type: String,
      default: '',
    },
    isFixed: {
      type: Boolean,
      default: false,
    },
    isSearch: {
      type: Boolean,
      default: false,
    },
    showSearchIput: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      curIndex: this.defaultCurIndex,
      searchInput: '',
      showStickyHolder: false,
    }
  },
  created() {
    this.$emit('update:isSearch', this.isSearch)
  },
  methods: {
    enterSearch() {
      this.$emit('update:showSearchIput', true)
      this.$emit('enter-search', this.searchInput)
    },
    clickSearchIcon() {
      this.$emit('update:showSearchIput', true)
      this.$emit('click-search-icon')
    },
    selectTab(item, index) {
      this.curIndex = index
      this.$emit('select-tab', { item, index })
    },
    throttle(after, wait) {
      /*option说明:after [回调函数]; 
                    wait  [周期性执行回调间隔时间ms]
      */
      var timer
      var isScroll //是否正在执行回调
      return function() {
        if (isScroll) return //在回调函数未执行完以前
        isScroll = true
        timer && clearTimeout(timer)
        timer = setTimeout(function() {
          after && after()
          isScroll = false
          timer = null
        }, wait)
      }
    },
    fixedScroll() {
      // 固定顶部导航
      let mainWrapper = document.getElementById('main-wrap')
      let tabHead = this.$refs.tabHead
      let offsetTop = mainWrapper && mainWrapper.offsetTop
      if (mainWrapper && this.isFixed) {
        mainWrapper.addEventListener(
          'scroll',
          this.throttle(() => {
            if (mainWrapper.scrollTop > 20) {
              tabHead.style.position = 'fixed'
              tabHead.style.zIndex = 2
              tabHead.style.top = offsetTop + 'px'
              tabHead.style.width = '600px'
              tabHead.style.transition = 'top 0.3s ease 0.3s'
              this.showStickyHolder = true
            } else {
              tabHead.style.position = 'static'
              tabHead.style.zIndex = 0
              tabHead.style.top = 0 + 'px'
              tabHead.style.transition = 'top 0.3s ease 0.3s'
              this.showStickyHolder = false
            }
          }, 200),
          false,
        )
      }
    },
    watchDocumentClick() {
      document.addEventListener('click', this.setShow, false)
    },
    setShow() {
      this.$emit('update:showSearchIput', false)
      this.$emit('update:isSearch', true)
    },
  },
  watch: {
    defaultCurIndex(val) {
      this.curIndex = val
    },
    isSearch(val) {
      this.isShow = val
    },
  },
  mounted() {
    this.$nextTick(() => {
      if (this.isFixed) {
        this.fixedScroll()
      }
      this.watchDocumentClick()
    })
  },
  beforeCreate() {
    document.removeEventListener('click', this.setShow)
  },
}
</script>

<style lang="scss" scoped>
.fade-enter-active {
  transition: all 0.3s ease;
}
.fade-leave-active {
  transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
}
.fade-enter, .fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
  opacity: 0;
}
.fy-tab-head-wrap {
  width: auto;
  transform: translateZ(0); // 用于防抖作用
  -webkit-font-smoothing: subpixel-antialiased;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  min-width: auto;
  transition: top 0.3s ease 0.3s;
  -moz-transition: top 0.3s ease 0.3s; /* Firefox 4 */
  -webkit-transition: top 0.3s ease 0.3s; /* Safari 和 Chrome */
  -o-transition: top 0.3s ease 0.3s; /* Opera */
  background: $color-fff;
  border-top-left-radius: 10px;
  border-top-right-radius: 10px;
  .tab-title-list {
    position: relative;
    .search {
      box-sizing: border-box;
      border: 1px solid $color-ef985e;
      line-height: 0px;
      border-radius: 14px;
      display: flex;
      -webkit-box-align: center;
      -ms-flex-align: center;
      align-items: center;
      justify-content: center;
      padding-left: 10px;
      padding-right: 10px;
      .icon {
        display: inline-block;
        cursor: pointer;
        width: 24px;
        height: 24px;
        background: url('~@img/tabHead/search.sel.svg') no-repeat center;
        background-size: 100% 100%;
      }
      .fyinput {
        display: inline-block;
      }
    }
    .search-icon {
      display: inline-block;
      position: absolute;
      cursor: pointer;
      right: 20px;
      align-items: center;
      width: 24px;
      height: 24px;
      background: url('~@img/common/search.svg') no-repeat center;
    }
    padding: 8px 0 0 30px;
    box-sizing: border-box;
    display: flex;
    flex-direction: row;
    align-items: center;
    width: 100%;
    border-bottom: 1px solid $color-333a;
    li {
      height: 40px;
      line-height: 40px;
      margin-right: 40px;
      span {
        display: block;
        &.tab-item {
          text-align: center;
          color: $color-666;
          font-weight: $font-weight-500;
          font-size: $font-size-16;

          &:last-child {
            margin-right: 0;
          }
          &:hover {
            cursor: pointer;
          }
          &.active {
            font-size: $font-size-16;
            font-family: $font-family;
            font-weight: $font-weight-600;
            color: $color-333;
            @include themify() {
              border-bottom: 2px solid themed('color');
            }
          }
        }
      }
    }
  }
}
</style>

729c3660fe41dbd4ba7efceab5e6411c.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值