Skip to content

Commit 66fbfac

Browse files
authored
refactor(Tab): refactor component with Sticky (youzan#2285)
fix youzan#2253 youzan#2122 Tab support css variables
1 parent 13b05cf commit 66fbfac

File tree

11 files changed

+240
-356
lines changed

11 files changed

+240
-356
lines changed

example/pages/tab/index.wxml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
</demo-block>
5858

5959
<demo-block title="样式风格">
60-
<van-tabs type="card" tab-class="tab-class" tab-active-class="tab-active-class">
60+
<van-tabs type="card" tab-class="tab-class">
6161
<van-tab
6262
wx:for="123"
6363
wx:key="index"

example/pages/tab/index.wxss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ page {
1414
.right-nav {
1515
padding: 0 10px;
1616
line-height: 44px !important;
17+
background-color: #fff;
1718
}
1819

1920
.tab-class {

packages/common/style/var.less

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,20 @@
442442
@tabbar-item-icon-size: 18px;
443443
@tabbar-item-margin-bottom: 5px;
444444

445+
// Tab
446+
@tab-text-color: @gray-darker;
447+
@tab-active-text-color: @text-color;
448+
@tab-disabled-text-color: @gray;
449+
@tab-font-size: @font-size-md;
450+
451+
// Tabs
452+
@tabs-default-color: @red;
453+
@tabs-line-height: 44px;
454+
@tabs-card-height: 30px;
455+
@tabs-nav-background-color: @white;
456+
@tabs-bottom-bar-height: 3px;
457+
@tabs-bottom-bar-color: @tabs-default-color;
458+
445459
// Tag
446460
@tag-padding: .2em .5em;
447461
@tag-font-size: @font-size-xs;

packages/sticky/index.less

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
.van-sticky {
22
position: relative;
3+
4+
&-wrap {
5+
&--fixed {
6+
position: fixed;
7+
right: 0;
8+
left: 0;
9+
}
10+
}
311
}

packages/sticky/index.ts

Lines changed: 42 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import { VantComponent } from '../common/component';
2-
import { nextTick } from '../common/utils';
3-
4-
type Position = 'top' | 'bottom' | '';
52

63
VantComponent({
74
props: {
@@ -12,131 +9,69 @@ VantComponent({
129
offsetTop: {
1310
type: Number,
1411
value: 0
15-
}
12+
},
13+
disabled: Boolean
1614
},
1715

1816
data: {
19-
position: '', // 当前定位
20-
height: 0,
2117
wrapStyle: '',
2218
containerStyle: ''
2319
},
2420

2521
methods: {
26-
setWrapStyle() {
27-
const { offsetTop, position } = this.data;
28-
let wrapStyle: string;
29-
let containerStyle: string;
30-
31-
switch (position) {
32-
case 'top':
33-
wrapStyle = `
34-
top: ${offsetTop}px;
35-
position: fixed;
36-
`;
37-
containerStyle = `height: ${this.itemHeight}px;`;
38-
break;
39-
case 'bottom':
40-
wrapStyle = `
41-
top: auto;
42-
bottom: 0;
43-
`;
44-
containerStyle = '';
45-
break;
46-
default:
47-
wrapStyle = '';
48-
containerStyle = '';
49-
}
50-
51-
const data: Record<string, string> = {};
52-
53-
if (wrapStyle !== this.data.wrapStyle) {
54-
data.wrapStyle = wrapStyle;
55-
}
56-
57-
if (containerStyle !== this.data.containerStyle) {
58-
data.containerStyle = containerStyle;
59-
}
22+
setStyle() {
23+
const { offsetTop, height, fixed, zIndex } = this.data;
6024

61-
if (JSON.stringify(data) !== '{}') {
62-
this.setData(data);
63-
}
64-
},
65-
66-
setPosition(position: Position) {
67-
if (position !== this.data.position) {
68-
this.setData({ position });
69-
nextTick(() => {
70-
this.setWrapStyle();
25+
if (fixed) {
26+
this.setData({
27+
wrapStyle: `top: ${offsetTop}px;`,
28+
containerStyle: `height: ${height}px; z-index: ${zIndex};`
29+
});
30+
} else {
31+
this.setData({
32+
wrapStyle: '',
33+
containerStyle: ''
7134
});
7235
}
7336
},
7437

7538
observerContentScroll() {
76-
const { offsetTop = 0 } = this.data;
77-
const { windowHeight } = wx.getSystemInfoSync();
78-
79-
this.createIntersectionObserver({}).disconnect();
80-
81-
// @ts-ignore
82-
this.createIntersectionObserver()
83-
.relativeToViewport({ top: -(this.itemHeight + offsetTop) })
84-
.observe(
85-
'.van-sticky',
86-
(res: WechatMiniprogram.ObserveCallbackResult) => {
87-
const { top } = res.boundingClientRect;
88-
89-
if (top > offsetTop) {
90-
return;
91-
}
92-
93-
const position: Position = 'top';
94-
95-
this.$emit('scroll', {
96-
scrollTop: top + offsetTop,
97-
isFixed: true
98-
});
99-
100-
this.setPosition(position);
39+
const { offsetTop } = this.data;
40+
const intersectionObserver = this.createIntersectionObserver({
41+
thresholds: [0, 1]
42+
});
43+
this.intersectionObserver = intersectionObserver;
44+
intersectionObserver.relativeToViewport({ top: -offsetTop });
45+
intersectionObserver.observe(
46+
'.van-sticky',
47+
(res) => {
48+
if (this.data.disabled) {
49+
return;
10150
}
102-
);
103-
104-
// @ts-ignore
105-
this.createIntersectionObserver()
106-
.relativeToViewport({ bottom: -(windowHeight - 1 - offsetTop) })
107-
.observe(
108-
'.van-sticky',
109-
(res: WechatMiniprogram.ObserveCallbackResult) => {
110-
const { top, bottom } = res.boundingClientRect;
111-
112-
if (bottom <= this.itemHeight - 1) {
113-
return;
114-
}
115-
116-
const position: Position = res.intersectionRatio > 0 ? 'top' : '';
117-
118-
this.$emit('scroll', {
119-
scrollTop: top + offsetTop,
120-
isFixed: position === 'top'
121-
});
122-
123-
this.setPosition(position);
124-
}
125-
);
51+
// @ts-ignore
52+
const { top, height } = res.boundingClientRect;
53+
const fixed = top <= offsetTop;
54+
55+
this.$emit('scroll', {
56+
scrollTop: top,
57+
isFixed: fixed
58+
});
59+
60+
this.setData({ fixed, height });
61+
62+
wx.nextTick(() => {
63+
this.setStyle();
64+
});
65+
}
66+
);
12667
}
12768
},
12869

12970
mounted() {
130-
this.getRect('.van-sticky').then(
131-
(rect: WechatMiniprogram.BoundingClientRectCallbackResult) => {
132-
this.itemHeight = rect.height;
133-
this.itemTop = rect.top;
134-
this.observerContentScroll();
135-
}
136-
);
71+
this.observerContentScroll();
13772
},
13873

13974
destroyed() {
140-
this.createIntersectionObserver({}).disconnect();
75+
this.intersectionObserver.disconnect();
14176
}
14277
});

packages/sticky/index.wxml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
<view class="custom-class van-sticky" style="z-index: {{ zIndex }}; {{ containerStyle }}">
2-
<view class="van-sticky-wrap" style="{{ wrapStyle }}">
1+
<wxs src="../wxs/utils.wxs" module="utils" />
2+
3+
<view class="custom-class van-sticky }}" style="{{ containerStyle }}">
4+
<view class="{{ utils.bem('sticky-wrap', { fixed }) }}" style="{{ wrapStyle }}">
35
<slot />
46
</view>
57
</view>

packages/tab/index.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import { VantComponent } from '../common/component';
33
VantComponent({
44
relation: {
55
name: 'tabs',
6-
type: 'ancestor'
6+
type: 'ancestor',
7+
linked(target) {
8+
this.parent = target;
9+
},
10+
unlinked() {
11+
this.parent = null;
12+
}
713
},
814

915
props: {
@@ -15,7 +21,6 @@ VantComponent({
1521
name: {
1622
type: [Number, String],
1723
value: '',
18-
observer: 'setComputedName'
1924
}
2025
},
2126

@@ -39,10 +44,16 @@ VantComponent({
3944
this.computedName = this.data.name || this.index;
4045
},
4146

47+
getComputedName() {
48+
if (this.data.name !== '') {
49+
return this.data.name;
50+
}
51+
return this.index;
52+
},
53+
4254
update() {
43-
const parent = this.getRelationNodes('../tabs/index')[0];
44-
if (parent) {
45-
parent.updateTabs();
55+
if (this.parent) {
56+
this.parent.updateTabs();
4657
}
4758
}
4859
}

packages/tabs/index.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"component": true,
33
"usingComponents": {
4-
"van-info": "../info/index"
4+
"van-info": "../info/index",
5+
"van-sticky": "../sticky/index"
56
}
67
}

0 commit comments

Comments
 (0)