mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[improvement] Tab: optimize event binding (#3512)
This commit is contained in:
parent
6e30dcb1d0
commit
c05124b3ec
@ -3,14 +3,14 @@ import { on, off } from '../utils/dom/event';
|
|||||||
export function BindEventMixin(handler) {
|
export function BindEventMixin(handler) {
|
||||||
function bind() {
|
function bind() {
|
||||||
if (!this.binded) {
|
if (!this.binded) {
|
||||||
handler.call(this, on);
|
handler.call(this, on, true);
|
||||||
this.binded = true;
|
this.binded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function unbind() {
|
function unbind() {
|
||||||
if (this.binded) {
|
if (this.binded) {
|
||||||
handler.call(this, off);
|
handler.call(this, off, false);
|
||||||
this.binded = false;
|
this.binded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -18,7 +18,7 @@ export function BindEventMixin(handler) {
|
|||||||
return {
|
return {
|
||||||
mounted: bind,
|
mounted: bind,
|
||||||
activated: bind,
|
activated: bind,
|
||||||
destroyed: unbind,
|
deactivated: unbind,
|
||||||
deactivated: unbind
|
beforeDestroy: unbind
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import { raf } from '../utils/dom/raf';
|
|||||||
import { on, off } from '../utils/dom/event';
|
import { on, off } from '../utils/dom/event';
|
||||||
import { TouchMixin } from '../mixins/touch';
|
import { TouchMixin } from '../mixins/touch';
|
||||||
import { ParentMixin } from '../mixins/relation';
|
import { ParentMixin } from '../mixins/relation';
|
||||||
|
import { BindEventMixin } from '../mixins/bind-event';
|
||||||
import {
|
import {
|
||||||
setScrollTop,
|
setScrollTop,
|
||||||
getScrollTop,
|
getScrollTop,
|
||||||
@ -14,7 +15,14 @@ const [sfc, bem] = use('tabs');
|
|||||||
const tabBem = use('tab')[1];
|
const tabBem = use('tab')[1];
|
||||||
|
|
||||||
export default sfc({
|
export default sfc({
|
||||||
mixins: [TouchMixin, ParentMixin('vanTabs')],
|
mixins: [
|
||||||
|
TouchMixin,
|
||||||
|
ParentMixin('vanTabs'),
|
||||||
|
BindEventMixin(function (bind, isBind) {
|
||||||
|
this.bindScrollEvent(isBind);
|
||||||
|
bind(window, 'resize', this.setLine, true);
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
model: {
|
model: {
|
||||||
prop: 'active'
|
prop: 'active'
|
||||||
@ -68,16 +76,13 @@ export default sfc({
|
|||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
this.scrollEvent = false;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
position: '',
|
position: '',
|
||||||
curActive: null,
|
curActive: null,
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
backgroundColor: this.color
|
backgroundColor: this.color
|
||||||
},
|
|
||||||
events: {
|
|
||||||
resize: false,
|
|
||||||
sticky: false,
|
|
||||||
swipeable: false
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -149,12 +154,8 @@ export default sfc({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
sticky() {
|
sticky(val) {
|
||||||
this.handlers(true);
|
this.bindScrollEvent(val);
|
||||||
},
|
|
||||||
|
|
||||||
swipeable() {
|
|
||||||
this.handlers(true);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -167,54 +168,23 @@ export default sfc({
|
|||||||
this.setLine();
|
this.setLine();
|
||||||
},
|
},
|
||||||
|
|
||||||
deactivated() {
|
|
||||||
this.handlers(false);
|
|
||||||
},
|
|
||||||
|
|
||||||
beforeDestroy() {
|
|
||||||
this.handlers(false);
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
onShow() {
|
onShow() {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.inited = true;
|
this.inited = true;
|
||||||
this.handlers(true);
|
|
||||||
this.scrollIntoView(true);
|
this.scrollIntoView(true);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// whether to bind sticky listener
|
bindScrollEvent(isBind) {
|
||||||
handlers(bind) {
|
const sticky = this.sticky && isBind;
|
||||||
const { events } = this;
|
|
||||||
const sticky = this.sticky && bind;
|
|
||||||
const swipeable = this.swipeable && bind;
|
|
||||||
|
|
||||||
// listen to window resize event
|
if (this.scrollEvent !== sticky) {
|
||||||
if (events.resize !== bind) {
|
this.scrollEvent = sticky;
|
||||||
events.resize = bind;
|
|
||||||
(bind ? on : off)(window, 'resize', this.setLine, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// listen to scroll event
|
|
||||||
if (events.sticky !== sticky) {
|
|
||||||
events.sticky = sticky;
|
|
||||||
this.scrollEl = this.scrollEl || getScrollEventTarget(this.$el);
|
this.scrollEl = this.scrollEl || getScrollEventTarget(this.$el);
|
||||||
(sticky ? on : off)(this.scrollEl, 'scroll', this.onScroll, true);
|
(sticky ? on : off)(this.scrollEl, 'scroll', this.onScroll, true);
|
||||||
this.onScroll();
|
this.onScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// listen to touch event
|
|
||||||
if (events.swipeable !== swipeable) {
|
|
||||||
events.swipeable = swipeable;
|
|
||||||
const { content } = this.$refs;
|
|
||||||
const action = swipeable ? on : off;
|
|
||||||
|
|
||||||
action(content, 'touchstart', this.touchStart);
|
|
||||||
action(content, 'touchmove', this.touchMove);
|
|
||||||
action(content, 'touchend', this.onTouchEnd);
|
|
||||||
action(content, 'touchcancel', this.onTouchEnd);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// watch swipe touch end
|
// watch swipe touch end
|
||||||
@ -434,6 +404,16 @@ export default sfc({
|
|||||||
</div>
|
</div>
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let contentListeners;
|
||||||
|
if (this.swipeable) {
|
||||||
|
contentListeners = {
|
||||||
|
touchstart: this.touchStart,
|
||||||
|
touchmove: this.touchMove,
|
||||||
|
touchend: this.onTouchEnd,
|
||||||
|
touchcancel: this.onTouchEnd
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={bem([type])}>
|
<div class={bem([type])}>
|
||||||
<div
|
<div
|
||||||
@ -451,7 +431,7 @@ export default sfc({
|
|||||||
{this.slots('nav-right')}
|
{this.slots('nav-right')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div ref="content" class={bem('content', { animated })}>
|
<div class={bem('content', { animated })} {...{ on: contentListeners }}>
|
||||||
{animated ? (
|
{animated ? (
|
||||||
<div class={bem('track')} style={this.trackStyle}>
|
<div class={bem('track')} style={this.trackStyle}>
|
||||||
{this.slots()}
|
{this.slots()}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user