<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>