feat(Tabbar): add placeholder prop (#5979)

This commit is contained in:
neverland 2020-04-01 20:41:04 +08:00 committed by GitHub
parent 0698872285
commit 02e67fdd47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 70 additions and 17 deletions

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`placeholder prop 1`] = ` exports[`placeholder prop 1`] = `
<div class="van-nav-bar__placeholder" style="height: 0px;"> <div class="van-nav-bar__placeholder" style="height: 50px;">
<div class="van-nav-bar van-nav-bar--fixed van-hairline--bottom"> <div class="van-nav-bar van-nav-bar--fixed van-hairline--bottom">
<div class="van-nav-bar__left"></div> <div class="van-nav-bar__left"></div>
<div class="van-nav-bar__title van-ellipsis"></div> <div class="van-nav-bar__title van-ellipsis"></div>

View File

@ -1,5 +1,5 @@
import NavBar from '..'; import NavBar from '..';
import { mount } from '../../../test'; import { mount, mockGetBoundingClientRect } from '../../../test';
test('render left & right slot', () => { test('render left & right slot', () => {
const wrapper = mount(NavBar, { const wrapper = mount(NavBar, {
@ -23,6 +23,8 @@ test('render title slot', () => {
}); });
test('placeholder prop', () => { test('placeholder prop', () => {
const restore = mockGetBoundingClientRect({ height: 50 });
const wrapper = mount(NavBar, { const wrapper = mount(NavBar, {
propsData: { propsData: {
fixed: true, fixed: true,
@ -31,6 +33,8 @@ test('placeholder prop', () => {
}); });
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
restore();
}); });
test('click-left event', () => { test('click-left event', () => {

View File

@ -163,6 +163,7 @@ export default {
| active-color | Color of active tab item | *string* | `#1989fa` | | active-color | Color of active tab item | *string* | `#1989fa` |
| inactive-color | Color of inactive tab item | *string* | `#7d7e80` | | inactive-color | Color of inactive tab item | *string* | `#7d7e80` |
| route | Whether to enable route mode | *boolean* | `false` | | route | Whether to enable route mode | *boolean* | `false` |
| placeholder `v2.6.0` | Whether to generage a placeholder element when fixed | *boolean* | `false` |
| safe-area-inset-bottom | Whether to enable bottom safe area adaptation | *boolean* | `false` | | safe-area-inset-bottom | Whether to enable bottom safe area adaptation | *boolean* | `false` |
### Tabbar Events ### Tabbar Events

View File

@ -170,6 +170,7 @@ export default {
| active-color | 选中标签的颜色 | *string* | `#1989fa` | | active-color | 选中标签的颜色 | *string* | `#1989fa` |
| inactive-color | 未选中标签的颜色 | *string* | `#7d7e80` | | inactive-color | 未选中标签的颜色 | *string* | `#7d7e80` |
| route | 是否开启路由模式 | *boolean* | `false` | | route | 是否开启路由模式 | *boolean* | `false` |
| placeholder `v2.6.0` | 固定在底部时,是否在标签位置生成一个等高的占位元素 | *boolean* | `false` |
| safe-area-inset-bottom | 是否开启[底部安全区适配](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei),设置 fixed 时默认开启 | *boolean* | `false` | | safe-area-inset-bottom | 是否开启[底部安全区适配](#/zh-CN/quickstart#di-bu-an-quan-qu-gua-pei),设置 fixed 时默认开启 | *boolean* | `false` |
### Tabbar Events ### Tabbar Events

View File

@ -10,6 +10,7 @@ export default createComponent({
props: { props: {
route: Boolean, route: Boolean,
zIndex: [Number, String], zIndex: [Number, String],
placeholder: Boolean,
activeColor: String, activeColor: String,
inactiveColor: String, inactiveColor: String,
value: { value: {
@ -30,6 +31,12 @@ export default createComponent({
}, },
}, },
data() {
return {
height: null,
};
},
computed: { computed: {
fit() { fit() {
if (this.safeAreaInsetBottom !== null) { if (this.safeAreaInsetBottom !== null) {
@ -45,6 +52,12 @@ export default createComponent({
children: 'setActiveItem', children: 'setActiveItem',
}, },
mounted() {
if (this.placeholder && this.fixed) {
this.height = this.$refs.tabbar.getBoundingClientRect().height;
}
},
methods: { methods: {
setActiveItem() { setActiveItem() {
this.children.forEach((item, index) => { this.children.forEach((item, index) => {
@ -58,22 +71,35 @@ export default createComponent({
this.$emit('change', active); this.$emit('change', active);
} }
}, },
genTabbar() {
return (
<div
ref="tabbar"
style={{ zIndex: this.zIndex }}
class={[
{ [BORDER_TOP_BOTTOM]: this.border },
bem({
unfit: !this.fit,
fixed: this.fixed,
}),
]}
>
{this.slots()}
</div>
);
},
}, },
render() { render() {
return ( if (this.placeholder && this.fixed) {
<div return (
style={{ zIndex: this.zIndex }} <div class={bem('placeholder')} style={{ height: `${this.height}px` }}>
class={[ {this.genTabbar()}
{ [BORDER_TOP_BOTTOM]: this.border }, </div>
bem({ );
unfit: !this.fit, }
fixed: this.fixed,
}), return this.genTabbar();
]}
>
{this.slots()}
</div>
);
}, },
}); });

View File

@ -2,6 +2,12 @@
exports[`disable border 1`] = `<div class="van-tabbar van-tabbar--fixed"></div>`; exports[`disable border 1`] = `<div class="van-tabbar van-tabbar--fixed"></div>`;
exports[`placeholder prop 1`] = `
<div class="van-tabbar__placeholder" style="height: 50px;">
<div class="van-hairline--top-bottom van-tabbar van-tabbar--fixed"></div>
</div>
`;
exports[`route mode 1`] = ` exports[`route mode 1`] = `
<div class="van-hairline--top-bottom van-tabbar van-tabbar--fixed"> <div class="van-hairline--top-bottom van-tabbar van-tabbar--fixed">
<div class="van-tabbar-item van-tabbar-item--active"> <div class="van-tabbar-item van-tabbar-item--active">

View File

@ -1,5 +1,5 @@
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import { mount, later } from '../../../test'; import { mount, later, mockGetBoundingClientRect } from '../../../test';
import Vue from 'vue'; import Vue from 'vue';
import Tabbar from '..'; import Tabbar from '..';
@ -174,3 +174,18 @@ test('disable border', () => {
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
test('placeholder prop', () => {
const restore = mockGetBoundingClientRect({ height: 50 });
const wrapper = mount(Tabbar, {
propsData: {
fixed: true,
placeholder: true,
},
});
expect(wrapper).toMatchSnapshot();
restore();
});