| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363 | 
							- <template>
 
-     <view class="tabs">
 
-         <scroll-view ref="tabbar1" id="tab-bar" class="tab-bar" :scroll="false" :scroll-x="true" :show-scrollbar="false"
 
-             :scroll-into-view="scrollInto">
 
-             <view style="flex-direction: column;">
 
-                 <view style="flex-direction: row;">
 
-                     <view class="uni-tab-item" v-for="(tab,index) in tabList" :key="tab.id" :id="tab.id" :ref="'tabitem'+index"
 
-                         :data-id="index" :data-current="index" @click="ontabtap">
 
-                         <text class="uni-tab-item-title" :class="tabIndex==index ? 'uni-tab-item-title-active' : ''">{{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>
 
-                 </view>
 
-             </view>
 
-         </scroll-view>
 
-         <view class="tab-bar-line"></view>
 
-         <swiper class="tab-view" ref="swiper1" id="tab-bar-view" :current="tabIndex" :duration="300" @change="onswiperchange"
 
-             @transition="onswiperscroll" @animationfinish="animationfinish" @onAnimationEnd="animationfinish">
 
-             <swiper-item class="swiper-item" v-for="(page, index) in tabList" :key="index">
 
-                 <!-- #ifndef MP-ALIPAY -->
 
-                 <swiperPage class="swiper-page" :pid="page.pageid" ref="page"></swiperPage>
 
-                 <!-- #endif -->
 
-                 <!-- #ifdef MP-ALIPAY -->
 
-                 <swiperPage class="swiper-page" :pid="page.pageid" :ref="'page' + index"></swiperPage>
 
-                 <!-- #endif -->
 
-             </swiper-item>
 
-         </swiper>
 
-     </view>
 
- </template>
 
- <script>
 
-     // #ifdef APP-NVUE
 
-     const dom = weex.requireModule('dom');
 
-     // #endif
 
-     // 缓存每页最多
 
-     const MAX_CACHE_DATA = 100;
 
-     // 缓存页签数量
 
-     const MAX_CACHE_PAGE = 3;
 
-     const TAB_PRELOAD_OFFSET = 1;
 
-     import swiperPage from './swiper-page.nvue';
 
-     export default {
 
-         components: {
 
-             swiperPage
 
-         },
 
-         data() {
 
-             return {
 
-                 tabList: [],
 
-                 tabIndex: 0,
 
-                 cacheTab: [],
 
-                 scrollInto: "",
 
-                 indicatorLineLeft: 0,
 
-                 indicatorLineWidth: 0,
 
-                 isTap: false
 
-             }
 
-         },
 
-         onLoad() {
 
-             for (var i = 0; i < 6; i++) {
 
-                 this.tabList.push({
 
-                     id: "tab" + i,
 
-                     name: 'Tab ' + (i + 1),
 
-                     pageid: i + 1
 
-                 })
 
-             }
 
-         },
 
-         onReady() {
 
-             this._lastTabIndex = 0;
 
-             this.swiperWidth = 0;
 
-             this.tabbarWidth = 0;
 
-             this.tabListSize = {};
 
-             this._touchTabIndex = 0;
 
-             // #ifndef MP-ALIPAY
 
-             this.pageList = this.$refs.page;
 
-             // #endif
 
-             // #ifdef MP-ALIPAY
 
-             this.pageList = [];
 
-             for (var i = 0; i < this.tabList.length; i++) {
 
-                 this.pageList.push(this.$refs['page' + i][0]);
 
-             }
 
-             // #endif
 
-             this.switchTab(this.tabIndex);
 
-             this.getTabbarItemsSize();
 
-         },
 
-         methods: {
 
-             ontabtap(e) {
 
-                 let index = e.target.dataset.current || e.currentTarget.dataset.current;
 
-                 // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-QQ
 
-                 this.isTap = true;
 
-                 var currentSize = this.tabListSize[index];
 
-                 this.updateIndicator(currentSize.left, currentSize.width);
 
-                 this._touchTabIndex = index;
 
-                 // #endif
 
-                 this.switchTab(index);
 
-             },
 
-             onswiperchange(e) {
 
-                 // 注意:百度小程序会触发2次
 
-                 // #ifndef APP-PLUS || H5 || MP-WEIXIN || MP-QQ
 
-                 let index = e.target.current || e.detail.current;
 
-                 this.switchTab(index);
 
-                 // #endif
 
-             },
 
-             onswiperscroll(e) {
 
-                 if (this.isTap) {
 
-                     return;
 
-                 }
 
-                 var offsetX = e.detail.dx;
 
-                 var preloadIndex = this._lastTabIndex;
 
-                 if (offsetX > TAB_PRELOAD_OFFSET) {
 
-                     preloadIndex++;
 
-                 } else if (offsetX < -TAB_PRELOAD_OFFSET) {
 
-                     preloadIndex--;
 
-                 }
 
-                 if (preloadIndex === this._lastTabIndex || preloadIndex < 0 || preloadIndex > this.pageList.length - 1) {
 
-                     return;
 
-                 }
 
-                 if (this.pageList[preloadIndex].dataList.length === 0) {
 
-                     this.loadTabData(preloadIndex);
 
-                 }
 
-                 /// 计算 tabbar 底线
 
-                 // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-QQ
 
-                 var percentage = Math.abs(this.swiperWidth / offsetX);
 
-                 var currentSize = this.tabListSize[this._lastTabIndex];
 
-                 var preloadSize = this.tabListSize[preloadIndex];
 
-                 var lineL = currentSize.left + (preloadSize.left - currentSize.left) / percentage;
 
-                 var lineW = currentSize.width + (preloadSize.width - currentSize.width) / percentage;
 
-                 this.updateIndicator(lineL, lineW);
 
-                 // #endif
 
-             },
 
-             animationfinish(e) {
 
-                 // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-QQ
 
-                 let index = e.detail.current;
 
-                 if (this._touchTabIndex === index) {
 
-                     this.isTap = false;
 
-                 }
 
-                 this._lastTabIndex = index;
 
-                 this.switchTab(index);
 
-                 this.updateIndicator(this.tabListSize[index].left, this.tabListSize[index].width);
 
-                 // #endif
 
-             },
 
-             getTabbarItemsSize() {
 
-                 // #ifdef APP-NVUE
 
-                 // 查询 tabbar 宽度
 
-                 uni.createSelectorQuery().in(this).select('#tab-bar').boundingClientRect().exec(rect => {
 
-                     this.tabbarWidth = rect[0].width;
 
-                 });
 
-                 // 查询 tabview 宽度
 
-                 uni.createSelectorQuery().in(this).select('#tab-bar-view').boundingClientRect().exec(rect => {
 
-                     this.swiperWidth = rect[0].width;
 
-                 });
 
-                 // 因 nvue 暂不支持 class 查询
 
-                 var queryTabSize = uni.createSelectorQuery().in(this);
 
-                 for (var i = 0; i < this.tabList.length; i++) {
 
-                     queryTabSize.select('#' + this.tabList[i].id).boundingClientRect();
 
-                 }
 
-                 queryTabSize.exec(rects => {
 
-                     console.log(JSON.stringify(rects));
 
-                     rects.forEach((rect) => {
 
-                         this.tabListSize[rect.dataset.id] = rect;
 
-                     })
 
-                 });
 
-                 // #endif
 
-                 // #ifdef MP-WEIXIN || H5 || MP-QQ
 
-                 uni.createSelectorQuery().in(this).select('.tab-view').fields({
 
-                     dataset: true,
 
-                     size: true,
 
-                 }, (res) => {
 
-                     this.swiperWidth = res.width;
 
-                 }).exec();
 
-                 uni.createSelectorQuery().in(this).selectAll('.uni-tab-item').boundingClientRect((rects) => {
 
-                     rects.forEach((rect) => {
 
-                         this.tabListSize[rect.dataset.id] = rect;
 
-                     })
 
-                 }).exec();
 
-                 // #endif
 
-                 // #ifdef APP-NVUE || H5 || MP-WEIXIN || MP-QQ
 
-                 setTimeout(() => {
 
-                     this.updateIndicator(this.tabListSize[this.tabIndex].left, this.tabListSize[this.tabIndex].width);
 
-                 }, 100)
 
-                 // #endif
 
-             },
 
-             updateIndicator(left, width) {
 
-                 this.indicatorLineLeft = left;
 
-                 this.indicatorLineWidth = width;
 
-             },
 
-             switchTab(index) {
 
-                 if (this.pageList[index].dataList.length === 0) {
 
-                     this.loadTabData(index);
 
-                 }
 
-                 if (this.tabIndex === index) {
 
-                     return;
 
-                 }
 
-                 // 缓存 tabId
 
-                 if (this.pageList[this.tabIndex].dataList.length > MAX_CACHE_DATA) {
 
-                     let isExist = this.cacheTab.indexOf(this.tabIndex);
 
-                     if (isExist < 0) {
 
-                         this.cacheTab.push(this.tabIndex);
 
-                     }
 
-                 }
 
-                 this.tabIndex = index;
 
-                 // #ifdef APP-NVUE
 
-                 this.scrollTabTo(index);
 
-                 // #endif
 
-                 // #ifndef APP-NVUE
 
-                 this.scrollInto = this.tabList[index].id;
 
-                 // #endif
 
-                 // 释放 tabId
 
-                 if (this.cacheTab.length > MAX_CACHE_PAGE) {
 
-                     let cacheIndex = this.cacheTab[0];
 
-                     this.clearTabData(cacheIndex);
 
-                     this.cacheTab.splice(0, 1);
 
-                 }
 
-             },
 
-             scrollTabTo(index) {
 
-                 const el = this.$refs['tabitem' + index][0];
 
-                 let offset = 0;
 
-                 // TODO fix ios offset
 
-                 if (index > 0) {
 
-                     offset = this.tabbarWidth / 2 - this.tabListSize[index].width / 2;
 
-                     if (this.tabListSize[index].right < this.tabbarWidth / 2) {
 
-                         offset = this.tabListSize[0].width;
 
-                     }
 
-                 }
 
-                 dom.scrollToElement(el, {
 
-                     offset: -offset
 
-                 });
 
-             },
 
-             loadTabData(index) {
 
-                 this.pageList[index].loadData();
 
-             },
 
-             clearTabData(index) {
 
-                 this.pageList[index].clear();
 
-             }
 
-         }
 
-     }
 
- </script>
 
- <style>
 
-     /* #ifndef APP-PLUS */
 
-     page {
 
-         width: 100%;
 
-         min-height: 100%;
 
-         display: flex;
 
-     }
 
-     /* #endif */
 
-     .tabs {
 
-         flex: 1;
 
-         flex-direction: column;
 
-         overflow: hidden;
 
-         background-color: #ffffff;
 
-         /* #ifdef MP-ALIPAY || MP-BAIDU */
 
-         height: 100vh;
 
-         /* #endif */
 
-     }
 
-     .tab-bar {
 
-         width: 750rpx;
 
-         height: 84rpx;
 
-         flex-direction: row;
 
-         /* #ifndef APP-PLUS */
 
-         white-space: nowrap;
 
-         /* #endif */
 
-     }
 
-     /* #ifndef APP-NVUE */
 
-     .tab-bar ::-webkit-scrollbar {
 
-         display: none;
 
-         width: 0 !important;
 
-         height: 0 !important;
 
-         -webkit-appearance: none;
 
-         background: transparent;
 
-     }
 
-     /* #endif */
 
-     .scroll-view-indicator {
 
-         position: relative;
 
-         height: 2px;
 
-         background-color: transparent;
 
-     }
 
-     .scroll-view-underline {
 
-         position: absolute;
 
-         top: 0;
 
-         bottom: 0;
 
-         width: 0;
 
-         background-color: #007AFF;
 
-     }
 
-     .scroll-view-animation {
 
-         transition-duration: 0.2s;
 
-         transition-property: left;
 
-     }
 
-     .tab-bar-line {
 
-         height: 1rpx;
 
-         background-color: #cccccc;
 
-     }
 
-     .tab-view {
 
-         flex: 1;
 
-     }
 
-     .uni-tab-item {
 
-         /* #ifndef APP-PLUS */
 
-         display: inline-block;
 
-         /* #endif */
 
-         flex-wrap: nowrap;
 
-         padding-left: 25px;
 
-         padding-right: 25px;
 
-     }
 
-     .uni-tab-item-title {
 
-         color: #555;
 
-         font-size: 30rpx;
 
-         height: 80rpx;
 
-         line-height: 80rpx;
 
-         flex-wrap: nowrap;
 
-         /* #ifndef APP-PLUS */
 
-         white-space: nowrap;
 
-         /* #endif */
 
-     }
 
-     .uni-tab-item-title-active {
 
-         color: #007AFF;
 
-     }
 
-     .swiper-item {
 
-         flex: 1;
 
-         flex-direction: column;
 
-     }
 
-     .swiper-page {
 
-         flex: 1;
 
-         flex-direction: row;
 
-         position: absolute;
 
-         left: 0;
 
-         top: 0;
 
-         right: 0;
 
-         bottom: 0;
 
-     }
 
- </style>
 
 
  |