feat(Tab): add show-zero-badge prop (#9343)

This commit is contained in:
neverland 2021-08-27 10:54:16 +08:00 committed by GitHub
parent 125f77a48b
commit a0149d564a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 90 additions and 17 deletions

View File

@ -229,7 +229,7 @@ export default {
| type | Can be set to `line` `card` | _string_ | `line` | | type | Can be set to `line` `card` | _string_ | `line` |
| color | Tab color | _string_ | `#ee0a24` | | color | Tab color | _string_ | `#ee0a24` |
| background | Background color | _string_ | `white` | | background | Background color | _string_ | `white` |
| duration | Toggle tab's animation time | _number \| string_ | `0.3` | - | | duration | Toggle tab's animation time | _number \| string_ | `0.3` |
| line-width | Width of tab line | _number \| string_ | `40px` | | line-width | Width of tab line | _number \| string_ | `40px` |
| line-height | Height of tab line | _number \| string_ | `3px` | | line-height | Height of tab line | _number \| string_ | `3px` |
| animated | Whether to change tabs with animation | _boolean_ | `false` | | animated | Whether to change tabs with animation | _boolean_ | `false` |
@ -240,7 +240,7 @@ export default {
| lazy-render | Whether to enable tab content lazy render | _boolean_ | `true` | | lazy-render | Whether to enable tab content lazy render | _boolean_ | `true` |
| scrollspy | Whether to use scrollspy mode | _boolean_ | `false` | | scrollspy | Whether to use scrollspy mode | _boolean_ | `false` |
| offset-top | Sticky offset top , supports `px` `vw` `vh` `rem` unit, default `px` | _number \| string_ | `0` | | offset-top | Sticky offset top , supports `px` `vw` `vh` `rem` unit, default `px` | _number \| string_ | `0` |
| swipe-threshold | Set swipe tabs threshold | _number \| string_ | `5` | - | | swipe-threshold | Set swipe tabs threshold | _number \| string_ | `5` |
| title-active-color | Title active color | _string_ | - | | title-active-color | Title active color | _string_ | - |
| title-inactive-color | Title inactive color | _string_ | - | | title-inactive-color | Title inactive color | _string_ | - |
| before-change | Callback function before changing tabsreturn `false` to prevent changesupport return Promise | _(name: number \| string) => boolean \| Promise\<boolean\>_ | - | | before-change | Callback function before changing tabsreturn `false` to prevent changesupport return Promise | _(name: number \| string) => boolean \| Promise\<boolean\>_ | - |
@ -259,6 +259,7 @@ export default {
| replace | If true, the navigation will not leave a history record | _boolean_ | `false` | | replace | If true, the navigation will not leave a history record | _boolean_ | `false` |
| title-style | Custom title style | _string \| Array \| object_ | - | | title-style | Custom title style | _string \| Array \| object_ | - |
| title-class | Custom title class name | _string \| Array \| object_ | - | | title-class | Custom title class name | _string \| Array \| object_ | - |
| show-zero-badge `v3.2.2` | Whether to show badge when the value is zero | _boolean_ | `true` |
### Tabs Events ### Tabs Events

View File

@ -270,6 +270,7 @@ export default {
| replace | 是否在跳转时替换当前页面历史 | _boolean_ | `false` | | replace | 是否在跳转时替换当前页面历史 | _boolean_ | `false` |
| title-style | 自定义标题样式 | _string \| Array \| object_ | - | | title-style | 自定义标题样式 | _string \| Array \| object_ | - |
| title-class | 自定义标题类名 | _string \| Array \| object_ | - | | title-class | 自定义标题类名 | _string \| Array \| object_ | - |
| show-zero-badge `v3.2.2` | 当 badge 为数字 0 时,是否展示徽标 | _boolean_ | `true` |
### Tabs Events ### Tabs Events

View File

@ -10,7 +10,7 @@ import {
} from 'vue'; } from 'vue';
// Utils // Utils
import { createNamespace, extend, unknownProp } from '../utils'; import { createNamespace, extend, truthProp, unknownProp } from '../utils';
import { TABS_KEY } from '../tabs/Tabs'; import { TABS_KEY } from '../tabs/Tabs';
// Composables // Composables
@ -34,6 +34,7 @@ export default defineComponent({
disabled: Boolean, disabled: Boolean,
titleClass: unknownProp, titleClass: unknownProp,
titleStyle: [String, Object] as PropType<string | CSSProperties>, titleStyle: [String, Object] as PropType<string | CSSProperties>,
showZeroBadge: truthProp,
}), }),
setup(props, { slots }) { setup(props, { slots }) {

View File

@ -0,0 +1,50 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should not render zero badge when show-zero-badge prop is false 1`] = `
<div class="van-tabs van-tabs--line">
<div class="van-tabs__wrap">
<div role="tablist"
class="van-tabs__nav van-tabs__nav--line"
>
<div role="tab"
class="van-tab van-tab--active"
aria-selected="true"
>
<div class="van-badge__wrapper">
<span class="van-tab__text van-tab__text--ellipsis">
</span>
<div class="van-badge van-badge--fixed">
0
</div>
</div>
</div>
<div role="tab"
class="van-tab"
aria-selected="false"
>
<div class="van-badge__wrapper">
<span class="van-tab__text van-tab__text--ellipsis">
</span>
</div>
</div>
<div class="van-tabs__line"
style="transform: translateX(0px) translateX(-50%);"
>
</div>
</div>
</div>
<div class="van-tabs__content">
<div role="tabpanel"
class="van-tab__pane"
style
>
1
</div>
<div role="tabpanel"
class="van-tab__pane"
style="display: none;"
>
</div>
</div>
</div>
`;

View File

@ -28,3 +28,20 @@ test('should emit click-tab event when tab is clicked', async () => {
}) })
); );
}); });
test('should not render zero badge when show-zero-badge prop is false', async () => {
const wrapper = mount({
render() {
return (
<Tabs>
<Tab badge={0}>1</Tab>
<Tab badge={0} showZeroBadge={false}>
2
</Tab>
</Tabs>
);
},
});
await later();
expect(wrapper.html()).toMatchSnapshot();
});

View File

@ -30,6 +30,7 @@ import {
setRootScrollTop, setRootScrollTop,
ComponentInstance, ComponentInstance,
BORDER_TOP_BOTTOM, BORDER_TOP_BOTTOM,
pick,
} from '../utils'; } from '../utils';
import { scrollLeftTo, scrollTopTo } from './utils'; import { scrollLeftTo, scrollTopTo } from './utils';
@ -374,15 +375,11 @@ export default defineComponent({
children.map((item, index) => ( children.map((item, index) => (
<TabsTitle <TabsTitle
ref={setTitleRefs(index)} ref={setTitleRefs(index)}
dot={item.dot}
type={props.type} type={props.type}
badge={item.badge}
title={item.title}
color={props.color} color={props.color}
style={item.titleStyle} style={item.titleStyle}
class={item.titleClass} class={item.titleClass}
isActive={index === state.currentIndex} isActive={index === state.currentIndex}
disabled={item.disabled}
scrollable={scrollable.value} scrollable={scrollable.value}
renderTitle={item.$slots.title} renderTitle={item.$slots.title}
activeColor={props.titleActiveColor} activeColor={props.titleActiveColor}
@ -390,6 +387,13 @@ export default defineComponent({
onClick={(event: MouseEvent) => { onClick={(event: MouseEvent) => {
onClickTab(item, index, event); onClickTab(item, index, event);
}} }}
{...pick(item, [
'dot',
'badge',
'title',
'disabled',
'showZeroBadge',
])}
/> />
)); ));

View File

@ -1,5 +1,5 @@
import { computed, CSSProperties, defineComponent } from 'vue'; import { computed, CSSProperties, defineComponent } from 'vue';
import { createNamespace, isDef } from '../utils'; import { createNamespace, isDef, truthProp } from '../utils';
import { Badge } from '../badge'; import { Badge } from '../badge';
const [name, bem] = createNamespace('tab'); const [name, bem] = createNamespace('tab');
@ -19,19 +19,14 @@ export default defineComponent({
activeColor: String, activeColor: String,
renderTitle: Function, renderTitle: Function,
inactiveColor: String, inactiveColor: String,
showZeroBadge: truthProp,
}, },
setup(props) { setup(props) {
const style = computed(() => { const style = computed(() => {
const style: CSSProperties = {}; const style: CSSProperties = {};
const { const { type, color, disabled, isActive, activeColor, inactiveColor } =
type, props;
color,
disabled,
isActive,
activeColor,
inactiveColor,
} = props;
const isCard = type === 'card'; const isCard = type === 'card';
@ -65,7 +60,11 @@ export default defineComponent({
if (props.dot || (isDef(props.badge) && props.badge !== '')) { if (props.dot || (isDef(props.badge) && props.badge !== '')) {
return ( return (
<Badge dot={props.dot} content={props.badge}> <Badge
dot={props.dot}
content={props.badge}
showZero={props.showZeroBadge}
>
{Text} {Text}
</Badge> </Badge>
); );