fix(tab): line-width support string (#3628)

fix #3620
This commit is contained in:
rex 2020-09-22 14:55:53 +08:00 committed by GitHub
parent eca7dae310
commit 9bdfd34487
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 105 additions and 73 deletions

View File

@ -21,7 +21,7 @@ export function nextTick(fn: Function) {
}, 1000 / 30); }, 1000 / 30);
} }
let systemInfo: WechatMiniprogram.GetSystemInfoSyncResult = null; let systemInfo: WechatMiniprogram.GetSystemInfoSyncResult;
export function getSystemInfoSync() { export function getSystemInfoSync() {
if (systemInfo == null) { if (systemInfo == null) {
systemInfo = wx.getSystemInfoSync(); systemInfo = wx.getSystemInfoSync();
@ -54,3 +54,29 @@ export function requestAnimationFrame(cb: Function) {
cb(); cb();
}); });
} }
export function getRect(
this: WechatMiniprogram.Component.TrivialInstance,
selector: string
): Promise<WechatMiniprogram.BoundingClientRectCallbackResult> {
return new Promise((resolve) => {
wx.createSelectorQuery()
.in(this)
.select(selector)
.boundingClientRect()
.exec((rect = []) => resolve(rect[0]));
});
}
export function getAllRect(
this: WechatMiniprogram.Component.TrivialInstance,
selector: string
): Promise<WechatMiniprogram.BoundingClientRectCallbackResult[]> {
return new Promise((resolve) => {
wx.createSelectorQuery()
.in(this)
.selectAll(selector)
.boundingClientRect()
.exec((rect = []) => resolve(rect[0]));
});
}

View File

@ -1,7 +1,7 @@
import { VantComponent } from '../common/component'; import { VantComponent } from '../common/component';
import { touch } from '../mixins/touch'; import { touch } from '../mixins/touch';
import { Weapp } from 'definitions/weapp'; import { Weapp } from 'definitions/weapp';
import { isDef, addUnit } from '../common/utils'; import { getAllRect, getRect, isDef } from '../common/utils';
type TrivialInstance = WechatMiniprogram.Component.TrivialInstance; type TrivialInstance = WechatMiniprogram.Component.TrivialInstance;
@ -35,10 +35,7 @@ VantComponent({
swipeable: Boolean, swipeable: Boolean,
titleActiveColor: String, titleActiveColor: String,
titleInactiveColor: String, titleInactiveColor: String,
color: { color: String,
type: String,
observer: 'setLine',
},
animated: { animated: {
type: Boolean, type: Boolean,
observer() { observer() {
@ -55,7 +52,6 @@ VantComponent({
lineHeight: { lineHeight: {
type: [String, Number], type: [String, Number],
value: -1, value: -1,
observer: 'setLine',
}, },
active: { active: {
type: [String, Number], type: [String, Number],
@ -102,13 +98,15 @@ VantComponent({
}, },
data: { data: {
tabs: [], tabs: [] as Record<string, unknown>[],
lineStyle: '', lineStyle: '',
scrollLeft: 0, scrollLeft: 0,
scrollable: false, scrollable: false,
trackStyle: '', trackStyle: '',
currentIndex: null, currentIndex: 0,
container: null, container: null,
skipTransition: true,
lineOffsetLeft: 0,
}, },
mounted() { mounted() {
@ -223,54 +221,34 @@ VantComponent({
} }
}, },
setLine(skipTransition?: boolean) { setLine(skipTransition = false) {
if (this.data.type !== 'line') { if (this.data.type !== 'line') {
return; return;
} }
const { const { currentIndex } = this.data;
color,
duration,
currentIndex,
lineWidth,
lineHeight,
} = this.data;
this.getRect('.van-tab', true).then( Promise.all([
(rects: WechatMiniprogram.BoundingClientRectCallbackResult[] = []) => { getAllRect.call(this, '.van-tab'),
const rect = rects[currentIndex]; getRect.call(this, '.van-tabs__line'),
if (rect == null) { ]).then(([rects = [], lineRect]) => {
return; const rect = rects[currentIndex];
}
const height =
lineHeight !== -1
? `height: ${addUnit(lineHeight)}; border-radius: ${addUnit(
lineHeight
)};`
: '';
let left = rects if (rect == null) {
.slice(0, currentIndex) return;
.reduce((prev, curr) => prev + curr.width, 0);
left += (rect.width - lineWidth) / 2;
const transition = skipTransition
? ''
: `transition-duration: ${duration}s; -webkit-transition-duration: ${duration}s;`;
this.setData({
lineStyle: `
${height}
width: ${addUnit(lineWidth)};
background-color: ${color};
-webkit-transform: translateX(${left}px);
transform: translateX(${left}px);
${transition}
`,
});
} }
);
let lineOffsetLeft = rects
.slice(0, currentIndex)
.reduce((prev, curr) => prev + curr.width, 0);
lineOffsetLeft += (rect.width - lineRect.width) / 2;
this.setData({
lineOffsetLeft,
skipTransition,
});
});
}, },
// scroll active tab into view // scroll active tab into view
@ -282,23 +260,18 @@ VantComponent({
} }
Promise.all([ Promise.all([
this.getRect('.van-tab', true), getAllRect.call(this, '.van-tab'),
this.getRect('.van-tabs__nav'), getRect.call(this, '.van-tabs__nav'),
]).then( ]).then(([tabRects, navRect]) => {
([tabRects, navRect]: [ const tabRect = tabRects[currentIndex];
WechatMiniprogram.BoundingClientRectCallbackResult[], const offsetLeft = tabRects
WechatMiniprogram.BoundingClientRectCallbackResult .slice(0, currentIndex)
]) => { .reduce((prev, curr) => prev + curr.width, 0);
const tabRect = tabRects[currentIndex];
const offsetLeft = tabRects
.slice(0, currentIndex)
.reduce((prev, curr) => prev + curr.width, 0);
this.setData({ this.setData({
scrollLeft: offsetLeft - (navRect.width - tabRect.width) / 2, scrollLeft: offsetLeft - (navRect.width - tabRect.width) / 2,
}); });
} });
);
}, },
onTouchScroll(event: Weapp.TouchEvent) { onTouchScroll(event: Weapp.TouchEvent) {

View File

@ -20,7 +20,7 @@
style="{{ color ? 'border-color: ' + color : '' }}" style="{{ color ? 'border-color: ' + color : '' }}"
> >
<view class="{{ utils.bem('tabs__nav', [type, { complete: !ellipsis }]) }} nav-class" style="{{ getters.tabCardTypeBorderStyle(color, type) }}"> <view class="{{ utils.bem('tabs__nav', [type, { complete: !ellipsis }]) }} nav-class" style="{{ getters.tabCardTypeBorderStyle(color, type) }}">
<view wx:if="{{ type === 'line' }}" class="van-tabs__line" style="{{ lineStyle }}" /> <view wx:if="{{ type === 'line' }}" class="van-tabs__line" style="{{ getters.lineStyle({ color, lineOffsetLeft, lineHeight, skipTransition, duration, lineWidth }) }}" />
<view <view
wx:for="{{ tabs }}" wx:for="{{ tabs }}"
wx:key="index" wx:key="index"
@ -60,4 +60,4 @@
<slot /> <slot />
</view> </view>
</view> </view>
</view> </view>

View File

@ -1,4 +1,6 @@
/* eslint-disable */ /* eslint-disable */
var utils = require('../wxs/utils.wxs');
function tabClass(active, ellipsis) { function tabClass(active, ellipsis) {
var classes = ['tab-class']; var classes = ['tab-class'];
@ -68,11 +70,42 @@ function trackStyle(data) {
return [ return [
'transform: translate3d(' + -100 * data.currentIndex + '%, 0, 0)', 'transform: translate3d(' + -100 * data.currentIndex + '%, 0, 0)',
'-webkit-transition-duration: ' + data.duration + 's', '-webkit-transition-duration: ' + data.duration + 's',
'transition-duration: ' + data.duration + 's' 'transition-duration: ' + data.duration + 's',
].join(';'); ].join(';');
} }
module.exports.tabClass = tabClass; function lineStyle(data) {
module.exports.tabStyle = tabStyle; var styles = [
module.exports.trackStyle = trackStyle; ['width', utils.addUnit(data.lineWidth)],
module.exports.tabCardTypeBorderStyle = tabCardTypeBorderStyle; ['transform', 'translateX(' + data.lineOffsetLeft + 'px)'],
['-webkit-transform', 'translateX(' + data.lineOffsetLeft + 'px)'],
];
if (data.color) {
styles.push(['background-color', data.color]);
}
if (data.lineHeight !== -1) {
styles.push(['height', utils.addUnit(data.lineHeight)]);
styles.push(['border-radius', utils.addUnit(data.lineHeight)]);
}
if (!data.skipTransition) {
styles.push(['transition-duration', data.duration + 's']);
styles.push(['-webkit-transition-duration', data.duration + 's']);
}
return styles
.map(function (item) {
return item.join(':');
})
.join(';');
}
module.exports = {
tabClass: tabClass,
tabStyle: tabStyle,
trackStyle: trackStyle,
lineStyle: lineStyle,
tabCardTypeBorderStyle: tabCardTypeBorderStyle,
};