|
1 |
| -<!-- z-tabs v0.2.5 by-ZXLee --> |
| 1 | +<!-- z-tabs v0.3.0 by-ZXLee --> |
2 | 2 | <!-- github地址:https://github.com/SmileZXLee/uni-z-tabs -->
|
3 | 3 | <!-- dcloud地址:https://ext.dcloud.net.cn/plugin?name=z-tabs -->
|
4 |
| -<!-- 反馈QQ群:790460711 --> |
| 4 | +<!-- 反馈QQ群:371624008 --> |
5 | 5 |
|
6 | 6 | <template name="z-tabs">
|
7 |
| - <view class="z-tabs-conatiner" :style="[{background:bgColor}, tabsStyle]"> |
| 7 | + <view class="z-tabs-conatiner" :style="[{background:bgColor}, {height: unit==='rpx' ? '80rpx' : '40px'}, tabsStyle]"> |
8 | 8 | <view class="z-tabs-left">
|
9 | 9 | <slot name="left" />
|
10 | 10 | </view>
|
|
14 | 14 | <view class="z-tabs-list" :style="[tabsListStyle, {marginTop: -finalBottomSpace+'px'}]">
|
15 | 15 | <view :ref="`z-tabs-item-${index}`" :id="`z-tabs-item-${index}`" class="z-tabs-item" :style="[tabStyle]" v-for="(item,index) in list" :key="index" @click="tabsClick(index,item)">
|
16 | 16 | <view class="z-tabs-item-title-container">
|
17 |
| - <text :class="{'z-tabs-item-title':true,'z-tabs-item-title-disabled':item.disabled}" |
| 17 | + <text :class="{'z-tabs-item-title-rpx':unit==='rpx','z-tabs-item-title-px':unit==='px','z-tabs-item-title-disabled':item.disabled}" |
18 | 18 | :style="[{color:item.disabled?disabledColor:(currentIndex===index?activeColor:inactiveColor)},item.disabled?disabledStyle:(currentIndex===index?activeStyle:inactiveStyle)]">
|
19 | 19 | {{item[nameKey]||item}}
|
20 | 20 | </text>
|
21 |
| - <text v-if="item.badge&&_formatCount(item.badge.count).length" class="z-tabs-item-badge" :style="[badgeStyle]">{{_formatCount(item.badge.count)}}</text> |
| 21 | + <text v-if="item.badge&&_formatCount(item.badge.count).length" class="z-tabs-item-badge" :class="{'z-tabs-item-badge-rpx':unit==='rpx','z-tabs-item-badge-px':unit==='px'}" :style="[badgeStyle]">{{_formatCount(item.badge.count)}}</text> |
22 | 22 | </view>
|
23 | 23 | </view>
|
24 | 24 | </view>
|
|
47 | 47 | const weexDom = weex.requireModule('dom');
|
48 | 48 | const weexAnimation = weex.requireModule('animation');
|
49 | 49 | // #endif
|
| 50 | + import zTabsConfig from './config/index' |
50 | 51 |
|
51 | 52 | // #ifdef APP-HARMONY
|
52 | 53 | let screenWidth = 0;
|
53 | 54 | // #endif
|
54 |
| - |
55 |
| - import zTabsConfig from './config/index' |
56 |
| - |
57 |
| - //获取默认配置信息 |
| 55 | + // 获取默认配置信息 |
58 | 56 | function _gc(key, defaultValue) {
|
59 | 57 | let config = null;
|
60 | 58 | if (zTabsConfig && Object.keys(zTabsConfig).length) {
|
|
65 | 63 | const value = config[_toKebab(key)];
|
66 | 64 | return value === undefined ? defaultValue : value;
|
67 | 65 | }
|
68 |
| - //驼峰转短横线 |
| 66 | + // 驼峰转短横线 |
69 | 67 | function _toKebab(value) {
|
70 | 68 | return value.replace(/([A-Z])/g, "-$1").toLowerCase();
|
71 | 69 | }
|
| 70 | + // rpx => px,兼容鸿蒙 |
| 71 | + function rpx2px(rpx) { |
| 72 | + // #ifdef APP-HARMONY |
| 73 | + if (!screenWidth) { |
| 74 | + screenWidth = uni.getSystemInfoSync().screenWidth; |
| 75 | + } |
| 76 | + return (screenWidth * Number.parseFloat(rpx)) / 750; |
| 77 | + // #endif |
| 78 | + // #ifndef APP-HARMONY |
| 79 | + return uni.upx2px(rpx); |
| 80 | + // #endif |
| 81 | + } |
72 | 82 |
|
73 | 83 | /**
|
74 | 84 | * z-tabs 标签
|
|
96 | 106 | * @property {String} bg-color z-tabs背景色
|
97 | 107 | * @property {Object} tabs-style z-tabs样式
|
98 | 108 | * @property {Boolean} init-trigger-change 初始化时是否自动触发change事件
|
| 109 | + * @property {String} unit z-tabs中布局的单位,默认为rpx |
99 | 110 | * @event {Function(index,value)} change tabs改变时触发,index:当前切换到的index;value:当前切换到的value
|
100 | 111 | * @example <z-tabs :list="list"></z-tabs>
|
101 | 112 | */
|
|
113 | 124 | barCalcedWidth: 0,
|
114 | 125 | pxBarWidth: 0,
|
115 | 126 | scrollLeft: 0,
|
116 |
| - tabsSuperWidth: this.rpx2px(750), |
117 |
| - tabsWidth: this.rpx2px(750), |
118 |
| - tabsHeight: this.rpx2px(80), |
| 127 | + tabsSuperWidth: rpx2px(750), |
| 128 | + tabsWidth: rpx2px(750), |
| 129 | + tabsHeight: rpx2px(80), |
119 | 130 | tabsLeft: 0,
|
120 | 131 | tabsContainerWidth: 0,
|
121 | 132 | itemNodeInfos: [],
|
|
165 | 176 | type: [Number, String],
|
166 | 177 | default: _gc('barHeight',8)
|
167 | 178 | },
|
| 179 | + //swiper的宽度,单位rpx,支持传100、"100px"或"100rpx",默认为"750rpx" |
| 180 | + swiperWidth: { |
| 181 | + type: [Number, String], |
| 182 | + default: _gc('swiperWidth',750) |
| 183 | + }, |
168 | 184 | //滑块样式,其中的width和height将被barWidth和barHeight覆盖
|
169 | 185 | barStyle: {
|
170 | 186 | type: Object,
|
|
249 | 265 | initTriggerChange: {
|
250 | 266 | type: Boolean,
|
251 | 267 | default: _gc('initTriggerChange',false)
|
| 268 | + }, |
| 269 | + //z-tabs中布局的单位,默认为rpx |
| 270 | + unit: { |
| 271 | + type: String, |
| 272 | + default: _gc('unit', 'rpx') |
252 | 273 | }
|
253 | 274 | },
|
254 | 275 | mounted() {
|
|
344 | 365 | return this._convertTextToPx(this.tabWidth);
|
345 | 366 | },
|
346 | 367 | finalBarWidth(){
|
347 |
| - return this._convertTextToPx(this.barWidth); |
| 368 | + return this._convertTextToPx(this._addUnit(this.barWidth, this.unit)); |
348 | 369 | },
|
349 | 370 | finalBarHeight(){
|
350 |
| - return this._convertTextToPx(this.barHeight); |
| 371 | + return this._convertTextToPx(this._addUnit(this.barHeight, this.unit)); |
| 372 | + }, |
| 373 | + finalSwiperWidth(){ |
| 374 | + return this._convertTextToPx(this.swiperWidth); |
351 | 375 | },
|
352 | 376 | finalBottomSpace(){
|
353 |
| - return this._convertTextToPx(this.bottomSpace); |
| 377 | + return this._convertTextToPx(this._addUnit(this.bottomSpace, this.unit)); |
354 | 378 | }
|
355 | 379 | },
|
356 | 380 | methods: {
|
357 |
| - // rpx => px,兼容鸿蒙 |
358 |
| - rpx2px(rpx) { |
359 |
| - // #ifdef APP-HARMONY |
360 |
| - if (!screenWidth) { |
361 |
| - screenWidth = uni.getSystemInfoSync().screenWidth; |
362 |
| - } |
363 |
| - return (screenWidth * Number.parseFloat(rpx)) / 750; |
364 |
| - // #endif |
365 |
| - // #ifndef APP-HARMONY |
366 |
| - return uni.upx2px(rpx); |
367 |
| - // #endif |
368 |
| - }, |
369 |
| - |
370 | 381 | //根据swiper的@transition实时更新底部dot位置
|
371 | 382 | setDx(dx) {
|
372 | 383 | if (!this.shouldSetDx) return;
|
373 | 384 | const isLineMode = this.barAnimateMode === 'line';
|
374 | 385 | const isWormMode = this.barAnimateMode === 'worm';
|
375 |
| - let dxRate = dx / this.tabsSuperWidth; |
| 386 | + let dxRate = dx / this.finalSwiperWidth; |
376 | 387 | this.currentSwiperIndex = this.currentIndex + parseInt(dxRate);
|
377 | 388 | const isRight = dxRate > 0;
|
378 | 389 | const barWidth = this.pxBarWidth;
|
|
389 | 400 | nextIndex = Math.min(nextIndex, this.itemNodeInfos.length - 1);
|
390 | 401 | const currentNodeInfo = this.itemNodeInfos[currentIndex];
|
391 | 402 | const nextNodeInfo = this.itemNodeInfos[nextIndex];
|
392 |
| - const nextBottomX = nextNodeInfo ? this._getBottomDotX(nextNodeInfo, barWidth) : 0; |
| 403 | + const nextBottomX = this._getBottomDotX(nextNodeInfo, barWidth); |
393 | 404 | if (isLineMode){
|
394 | 405 | this.bottomDotX = this.bottomDotXForIndex + (nextBottomX - this.bottomDotXForIndex) * Math.abs(dxRate);
|
395 | 406 | } else if (isWormMode) {
|
|
505 | 516 | if (nodeRes) {
|
506 | 517 | node = nodeRes[0];
|
507 | 518 | offset = this.currentScrollLeft;
|
508 |
| - this.tabsHeight = Math.max(node.height + this.rpx2px(28), this.tabsHeight); |
| 519 | + this.tabsHeight = Math.max(node.height + rpx2px(28), this.tabsHeight); |
509 | 520 | tabsContainerWidth = 0;
|
510 | 521 | for(let i = 0;i < this.itemNodeInfos.length;i++){
|
511 | 522 | let oldNode = this.itemNodeInfos[i];
|
512 | 523 | tabsContainerWidth += i === index ? node.width : oldNode.width;
|
513 | 524 | }
|
514 | 525 | }
|
515 | 526 | }
|
516 |
| - this.bottomDotX = this._getBottomDotX(node, this.finalBarWidth, offset); |
| 527 | + if (node) { |
| 528 | + this.bottomDotX = this._getBottomDotX(node, this.finalBarWidth, offset); |
| 529 | + } |
517 | 530 | this.bottomDotXForIndex = this.bottomDotX;
|
518 | 531 | if (this.tabsWidth) {
|
519 | 532 | setTimeout(()=>{
|
|
610 | 623 | _convertTextToPx(text) {
|
611 | 624 | const dataType = Object.prototype.toString.call(text);
|
612 | 625 | if (dataType === '[object Number]') {
|
613 |
| - return this.rpx2px(text); |
| 626 | + return rpx2px(text); |
614 | 627 | }
|
615 | 628 | let isRpx = false;
|
616 | 629 | if (text.indexOf('rpx') !== -1 || text.indexOf('upx') !== -1) {
|
|
619 | 632 | } else if (text.indexOf('px') !== -1) {
|
620 | 633 | text = text.replace('px', '');
|
621 | 634 | } else {
|
622 |
| - text = this.rpx2px(text); |
| 635 | + text = rpx2px(text); |
623 | 636 | }
|
624 | 637 | if (!isNaN(text)) {
|
625 |
| - if (isRpx) return Number(this.rpx2px(text)); |
| 638 | + if (isRpx) return Number(rpx2px(text)); |
626 | 639 | return Number(text);
|
627 | 640 | }
|
628 | 641 | return 0;
|
| 642 | + }, |
| 643 | + // 添加单位 |
| 644 | + _addUnit(value, unit) { |
| 645 | + if (Object.prototype.toString.call(value) === '[object String]') { |
| 646 | + let tempValue = value; |
| 647 | + tempValue = tempValue.replace('rpx', '').replace('upx', '').replace('px', ''); |
| 648 | + if (value.indexOf('rpx') === -1 && value.indexOf('upx') === -1 && value.indexOf('px') !== -1) { |
| 649 | + tempValue = parseFloat(tempValue) * 2; |
| 650 | + } |
| 651 | + value = tempValue; |
| 652 | + } |
| 653 | + return unit === 'rpx' ? value + 'rpx' : (value / 2) + 'px'; |
629 | 654 | }
|
630 | 655 | }
|
631 | 656 |
|
|
643 | 668 | width: 750rpx;
|
644 | 669 | /* #endif */
|
645 | 670 | flex-direction: row;
|
646 |
| - height: 80rpx; |
647 | 671 | }
|
648 | 672 |
|
649 | 673 | .z-tabs-scroll-view-conatiner{
|
|
713 | 737 | align-items: center;
|
714 | 738 | }
|
715 | 739 |
|
716 |
| - .z-tabs-item-title{ |
| 740 | + .z-tabs-item-title-rpx{ |
717 | 741 | font-size: 30rpx;
|
718 | 742 | }
|
719 | 743 |
|
| 744 | + .z-tabs-item-title-px{ |
| 745 | + font-size: 15px; |
| 746 | + } |
| 747 | + |
720 | 748 | .z-tabs-item-title-disabled{
|
721 | 749 | /* #ifndef APP-NVUE */
|
722 | 750 | cursor: not-allowed;
|
723 | 751 | /* #endif */
|
724 | 752 | }
|
725 | 753 |
|
726 | 754 | .z-tabs-item-badge{
|
727 |
| - margin-left: 8rpx; |
728 | 755 | background-color: #ec5b56;
|
729 | 756 | color: white;
|
730 |
| - font-size: 22rpx; |
731 | 757 | border-radius: 100px;
|
| 758 | + } |
| 759 | + |
| 760 | + .z-tabs-item-badge-rpx{ |
| 761 | + margin-left: 8rpx; |
| 762 | + font-size: 22rpx; |
732 | 763 | padding: 0rpx 10rpx;
|
733 | 764 | }
|
734 | 765 |
|
| 766 | + .z-tabs-item-badge-px{ |
| 767 | + margin-left: 4px; |
| 768 | + font-size: 11px; |
| 769 | + padding: 0px 5px; |
| 770 | + } |
| 771 | + |
735 | 772 | .z-tabs-bottom{
|
736 | 773 | position: absolute;
|
737 | 774 | bottom: 0;
|
|
0 commit comments