123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- <template>
- <scroll-view ref="tabbar1" id="tab-bar" class="tab-bar" :scroll="false" :scroll-x="true" :show-scrollbar="false"
- :scroll-into-view="scrollInto" :style="{height: height+'rpx'}">
- <view style="flex-direction: column;">
- <view style="flex-direction: row;">
- <view class="uni-tab-item" v-for="(tab,index) in tabList" :key="index" :id="'tab'+index"
- :ref="'tabitem'+index" :data-id="index" :data-current="index" @click="handleTab">
- <text class="uni-tab-item-title" :class="current==index ? 'uni-tab-item-title-active' : ''"
- :style="{height: (height - 6) + 'rpx',lineHeight: (height - 6) + 'rpx'}">{{tab.name}}</text>
- </view>
- </view>
- <view class="scroll-view-indicator">
- <view ref="underline" class="scroll-view-underline" :class="isTap ? 'scroll-view-animation':''"
- :style="{left: indicatorLineLeft + 'px', width: indicatorLineWidth + 'px'}">
- <view class="tabbar-tabline-border"></view>
- </view>
- </view>
- </view>
- </scroll-view>
- </template>
- <script>
- export default {
- name:"myTabbar",
- props: {
- current: {
- type: [Number,String],
- default: 0
- },
- tabList: {
- type: Array,
- default: []
- },
- // 是否可以滚动
- scrollable: {
- type: Boolean,
- default: false
- },
- // tab-bar高度
- height: {
- type: Number,
- default: 100
- },
- },
- data() {
- return {
- scrollInto: "",
- isTap: false,
- tabListSize: {},
- indicatorLineLeft: 0,
- indicatorLineWidth: 0
- };
- },
- watch: {
- current(val,old) {
- if(val == old) return
- this.scrollInto = 'tab'+this.current;
- },
- tabList: {
- handler() {
- this.tabListSize = {};
- this.$nextTick(()=>{
- this.scrollInto = 'tab'+this.current;
- this.selectorQuery();
- })
- },
- immediate: true
- }
- },
- methods: {
- swiperChange(index,isTap) {
- this.isTap = isTap
- this.updateIndicator(this.tabListSize['tab'+index].left, this.tabListSize['tab'+index].width);
- this.$emit("change",{
- index: index,
- isTap: this.isTap
- })
- },
- handleTab(e) {
- let index = e.target.dataset.current || e.currentTarget.dataset.current;
- this.isTap = true;
- var currentSize = this.tabListSize['tab'+index];
- this.updateIndicator(currentSize.left, currentSize.width);
- this._touchTabIndex = index;
- this.$emit("change",{
- index: index,
- isTap: this.isTap
- })
- },
- updateIndicator(left, width) {
- this.indicatorLineLeft = left;
- this.indicatorLineWidth = width;
- },
- selectorQuery() {
- if(this.tabList&&this.tabList.length > 0) {
- uni.createSelectorQuery().in(this).selectAll('.uni-tab-item').boundingClientRect((rects) => {
- rects.forEach((rect) => {
- this.tabListSize[rect.id] = rect;
- })
- this.updateIndicator(this.tabListSize['tab'+this.current].left, this.tabListSize['tab'+this.current].width);
- }).exec();
- }
- },
- }
- }
- </script>
- <style lang="scss" scoped>
- @mixin u-flex($flexD, $alignI, $justifyC) {
- display: flex;
- flex-direction: $flexD;
- align-items: $alignI;
- justify-content: $justifyC;
- }
- .tab-bar {
- width: 100vw;
- height: 100rpx;
- background-color: #fff;
- flex-direction: row;
- white-space: nowrap;
- font-family: PingFang SC, PingFang SC;
- font-weight: 400;
- font-size: 28rpx;
- color: #757575;
- }
-
- .tab-bar ::-webkit-scrollbar {
- display: none;
- width: 0 !important;
- height: 0 !important;
- -webkit-appearance: none;
- background: transparent;
- }
-
- .uni-tab-item {
- display: inline-block;
- flex-wrap: nowrap;
- min-width: 125rpx;
- box-sizing: border-box;
- text-align: center;
- padding-left: 20rpx;
- padding-right: 20rpx;
- }
-
- .uni-tab-item-title {
- height: 94rpx;
- line-height: 94rpx;
- flex-wrap: nowrap;
- white-space: nowrap;
- }
-
- .uni-tab-item-title-active {
- font-weight: 500;
- color: #333333;
- }
-
- .scroll-view-indicator {
- position: relative;
- height: 6rpx;
- background-color: transparent;
- }
-
- .scroll-view-underline {
- position: absolute;
- top: 0;
- bottom: 0;
- width: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .tabbar-tabline-border {
- width: 48rpx;
- height: 6rpx;
- background: #FF7700;
- border-radius: 3rpx 3rpx 3rpx 3rpx;
- }
-
- .scroll-view-animation {
- transition-duration: 0.2s;
- transition-property: left;
- }
- </style>
|