diff --git a/packages/popup/index.wxml b/packages/popup/index.wxml index 9b41e5c3..f3fd7cfa 100644 --- a/packages/popup/index.wxml +++ b/packages/popup/index.wxml @@ -1,4 +1,5 @@ + diff --git a/packages/popup/index.wxs b/packages/popup/index.wxs new file mode 100644 index 00000000..8c766dcd --- /dev/null +++ b/packages/popup/index.wxs @@ -0,0 +1,18 @@ +/* eslint-disable */ +var style = require('../wxs/style.wxs'); + +function popupClass(data) { + return style([ + { + 'z-index': data.zIndex, + '-webkit-transition-duration': data.currentDuration + 'ms', + 'transition-duration': data.currentDuration + 'ms', + }, + data.display ? null : 'display: none', + data.customStyle, + ]); +} + +module.exports = { + popupClass: popupClass, +}; diff --git a/packages/sticky/index.wxs b/packages/sticky/index.wxs index 18efe147..10eec72a 100644 --- a/packages/sticky/index.wxs +++ b/packages/sticky/index.wxs @@ -1,37 +1,24 @@ /* eslint-disable */ +var style = require('../wxs/style.wxs'); + function wrapStyle(data) { - var style = ''; - - if (data.transform) { - style += 'transform: translate3d(0, ' + data.transform + 'px, 0);'; - } - - if (data.fixed) { - style += 'top: ' + data.offsetTop + 'px;'; - } - - if (data.zIndex) { - style += 'z-index: ' + data.zIndex + ';'; - } - - return style; + return style({ + transform: data.transform + ? 'translate3d(0, ' + data.transform + 'px, 0)' + : '', + top: data.fixed ? data.offsetTop + 'px' : '', + 'z-index': data.zIndex, + }); } function containerStyle(data) { - var style = ''; - - if (data.fixed) { - style += 'height: ' + data.height + 'px;'; - } - - if (data.zIndex) { - style += 'z-index: ' + data.zIndex + ';'; - } - - return style; + return style({ + height: data.fixed ? data.height + 'px' : '', + 'z-index': data.zIndex, + }); } module.exports = { wrapStyle: wrapStyle, - containerStyle: containerStyle + containerStyle: containerStyle, }; diff --git a/packages/tab/README.md b/packages/tab/README.md index 12ed6cf7..59b518b5 100644 --- a/packages/tab/README.md +++ b/packages/tab/README.md @@ -181,38 +181,64 @@ Page({ ``` +## 常见问题 + +### 组件从隐藏状态切换到显示状态时,底部条位置错误? + +Tabs 组件在挂载时,会获取自身的宽度,并计算出底部条的位置。如果组件一开始处于隐藏状态,则获取到的宽度永远为 0,因此无法展示底部条位置。 + +#### 解决方法 + +方法一,使用 `v-if` 来控制组件展示,使组件重新初始化: + +```html + +``` + +方法二,调用组件的 resize 方法来主动触发重绘: + +```html + +``` + +```js +this.selectComponent('#tabs').resize(); +``` + ## API ### Tabs Props -| 参数 | 说明 | 类型 | 默认值 | 版本 | -| --- | --- | --- | --- | --- | -| active | 当前选中标签的标识符 | _string \| number_ | `0` | - | -| color | 标签颜色 | _string_ | `#ee0a24` | - | -| z-index | z-index 层级 | _number_ | `1` | - | -| type | 样式风格,可选值为`card` | _string_ | `line` | - | -| border | 是否展示外边框,仅在 `line` 风格下生效 | _boolean_ | `false` | - | -| duration | 动画时间 (单位秒) | _number_ | `0.3` | - | -| line-width | 底部条宽度 (px) | _string \| number_ | `40px` | - | -| line-height | 底部条高度 (px) | _string \| number_ | `3px` | - | -| swipe-threshold | 滚动阈值,设置标签数量超过多少个可滚动 | _number_ | `5` | - | -| animated | 是否使用动画切换 Tabs | _boolean_ | `false` | - | -| ellipsis | 是否省略过长的标题文字 | _boolean_ | `true` | - | -| sticky | 是否使用粘性定位布局 | _boolean_ | `false` | - | -| swipeable | 是否开启手势滑动切换 | _boolean_ | `false` | - | -| lazy-render | 是否开启标签页内容延迟渲染 | _boolean_ | `true` | - | -| offset-top | 粘性定位布局下与顶部的最小距离,单位`px` | _number_ | - | - | +| 参数 | 说明 | 类型 | 默认值 | +| --- | --- | --- | --- | +| type | 样式风格,可选值为`card` | _string_ | `line` | +| color | 标签主题色 | _string_ | `#ee0a24` | +| active | 当前选中标签的标识符 | _string \| number_ | `0` | +| duration | 动画时间,单位秒 | _number_ | `0.3` | +| line-width | 底部条宽度,默认单位`px` | _string \| number_ | `40px` | +| line-height | 底部条高度,默认单位`px` | _string \| number_ | `3px` | +| animated | 是否开启切换标签内容时的转场动画 | _boolean_ | `false` | +| border | 是否展示外边框,仅在 `line` 风格下生效 | _boolean_ | `false` | +| ellipsis | 是否省略过长的标题文字 | _boolean_ | `true` | +| sticky | 是否使用粘性定位布局 | _boolean_ | `false` | +| swipeable | 是否开启手势滑动切换 | _boolean_ | `false` | +| lazy-render | 是否开启标签页内容延迟渲染 | _boolean_ | `true` | +| offset-top | 粘性定位布局下与顶部的最小距离,单位`px` | _number_ | - | +| swipe-threshold | 滚动阈值,标签数量超过阈值且总宽度超过标签栏宽度时开始横向滚动 | _number_ | `5` | +| title-active-color | 标题选中态颜色 | _string_ | - | +| title-inactive-color | 标题默认态颜色 | _string_ | - | +| z-index | z-index 层级 | _number_ | `1` | ### Tab Props -| 参数 | 说明 | 类型 | 默认值 | 版本 | -| --- | --- | --- | --- | --- | -| name | 标签名称,作为匹配的标识符 | _string \| number_ | 标签的索引值 | - | -| title | 标题 | _string_ | - | - | -| disabled | 是否禁用标签 | _boolean_ | `false` | - | -| dot | 是否显示小红点 | _boolean_ | - | - | -| info | 图标右上角提示信息 | _string \| number_ | - | - | -| title-style | 自定义标题样式 | _string_ | - | - | +| 参数 | 说明 | 类型 | 默认值 | +| ----------- | -------------------------- | ------------------ | ------------ | +| name | 标签名称,作为匹配的标识符 | _string \| number_ | 标签的索引值 | +| title | 标题 | _string_ | - | +| disabled | 是否禁用标签 | _boolean_ | `false` | +| dot | 是否显示小红点 | _boolean_ | - | +| info | 图标右上角提示信息 | _string \| number_ | - | +| title-style | 自定义标题样式 | _string_ | - | ### Tabs Slot @@ -244,3 +270,11 @@ Page({ | nav-class | 标签栏样式类 | | tab-class | 标签样式类 | | tab-active-class | 标签激活态样式类 | + +### 方法 + +通过 selectComponent 可以获取到 Tabs 实例并调用实例方法 + +| 方法名 | 参数 | 返回值 | 介绍 | +| --- | --- | --- | --- | +| resize | - | - | 外层元素大小或组件显示状态变化时,可以调用此方法来触发重绘 | diff --git a/packages/tabs/index.ts b/packages/tabs/index.ts index 26677a3f..52742ee6 100644 --- a/packages/tabs/index.ts +++ b/packages/tabs/index.ts @@ -46,7 +46,7 @@ VantComponent({ lineWidth: { type: [String, Number], value: 40, - observer: 'setLine', + observer: 'resize', }, lineHeight: { type: [String, Number], @@ -110,7 +110,7 @@ VantComponent({ mounted() { wx.nextTick(() => { - this.setLine(true); + this.resize(true); this.scrollIntoView(); }); }, @@ -201,7 +201,7 @@ VantComponent({ this.setData({ currentIndex }); wx.nextTick(() => { - this.setLine(); + this.resize(); this.scrollIntoView(); this.updateContainer(); @@ -220,7 +220,7 @@ VantComponent({ } }, - setLine(skipTransition = false) { + resize(skipTransition = false) { if (this.data.type !== 'line') { return; } diff --git a/packages/tabs/index.wxml b/packages/tabs/index.wxml index dd92ac49..0dc346b2 100644 --- a/packages/tabs/index.wxml +++ b/packages/tabs/index.wxml @@ -1,5 +1,5 @@ - + - - + + @@ -55,7 +55,7 @@ > diff --git a/packages/tabs/index.wxs b/packages/tabs/index.wxs index 60c48fd4..a027c7b9 100644 --- a/packages/tabs/index.wxs +++ b/packages/tabs/index.wxs @@ -1,5 +1,6 @@ /* eslint-disable */ var utils = require('../wxs/utils.wxs'); +var style = require('../wxs/style.wxs'); function tabClass(active, ellipsis) { var classes = ['tab-class']; @@ -15,51 +16,33 @@ function tabClass(active, ellipsis) { return classes.join(' '); } -function tabStyle( - active, - ellipsis, - color, - type, - disabled, - activeColor, - inactiveColor, - swipeThreshold, - scrollable -) { - var styles = []; - var isCard = type === 'card'; +function tabStyle(data) { + var titleColor = data.active + ? data.titleActiveColor + : data.titleInactiveColor; + + var ellipsis = data.scrollable && data.ellipsis; + // card theme color - if (color && isCard) { - styles.push('border-color:' + color); - - if (!disabled) { - if (active) { - styles.push('background-color:' + color); - } else { - styles.push('color:' + color); - } - } + if (data.type === 'card') { + return style({ + 'border-color': data.color, + 'background-color': !data.disabled && data.active ? data.color : null, + color: titleColor || (!data.disabled && !data.active ? data.color : null), + 'flex-basis': ellipsis ? 88 / data.swipeThreshold + '%' : null, + }); } - var titleColor = active ? activeColor : inactiveColor; - if (titleColor) { - styles.push('color:' + titleColor); - } - - if (scrollable && ellipsis) { - styles.push('flex-basis:' + 88 / swipeThreshold + '%'); - } - - return styles.join(';'); + return style({ + color: titleColor, + 'flex-basis': ellipsis ? 88 / data.swipeThreshold + '%' : null, + }); } -function tabCardTypeBorderStyle(color, type) { - var isCard = type === 'card'; - var styles = []; - if (isCard && color) { - styles.push('border-color:' + color); - } - return styles.join(';'); +function navStyle(color, type) { + return style({ + 'border-color': type === 'card' && color ? color : null, + }); } function trackStyle(data) { @@ -67,43 +50,27 @@ function trackStyle(data) { return ''; } - return [ - ['left', -100 * data.currentIndex + '%'], - ['-webkit-transition-duration', data.duration + 's'], - ['transition-duration: ', data.duration + 's'], - ] - .map(function (item) { - return item.join(':'); - }) - .join(';'); + return style({ + left: -100 * data.currentIndex + '%', + 'transition-duration': data.duration + 's', + '-webkit-transition-duration': data.duration + 's', + }); } function lineStyle(data) { - var styles = [ - ['width', utils.addUnit(data.lineWidth)], - ['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(';'); + return style({ + width: utils.addUnit(data.lineWidth), + transform: 'translateX(' + data.lineOffsetLeft + 'px)', + '-webkit-transform': 'translateX(' + data.lineOffsetLeft + 'px)', + 'background-color': data.color, + height: data.lineHeight !== -1 ? utils.addUnit(data.lineHeight) : null, + 'border-radius': + data.lineHeight !== -1 ? utils.addUnit(data.lineHeight) : null, + 'transition-duration': !data.skipTransition ? data.duration + 's' : null, + '-webkit-transition-duration': !data.skipTransition + ? data.duration + 's' + : null, + }); } module.exports = { @@ -111,5 +78,5 @@ module.exports = { tabStyle: tabStyle, trackStyle: trackStyle, lineStyle: lineStyle, - tabCardTypeBorderStyle: tabCardTypeBorderStyle, + navStyle: navStyle, }; diff --git a/packages/wxs/style.wxs b/packages/wxs/style.wxs index 0c3d0180..3139cde4 100644 --- a/packages/wxs/style.wxs +++ b/packages/wxs/style.wxs @@ -1,15 +1,32 @@ /* eslint-disable */ var object = require('./object.wxs'); +var array = require('./array.wxs'); function style(styles) { - return object.keys(styles) - .filter(function (key) { - return styles[key] != null; - }) - .map(function (key) { - return [key, [styles[key]]].join(':'); - }) - .join(';'); + if (array.isArray(styles)) { + return styles + .filter(function (item) { + return item != null; + }) + .map(function (item) { + return style(item); + }) + .join(';'); + } + + if ('Object' === styles.constructor) { + return object + .keys(styles) + .filter(function (key) { + return styles[key] != null; + }) + .map(function (key) { + return [key, [styles[key]]].join(':'); + }) + .join(';'); + } + + return styles; } module.exports = style;