[improvement] Tab: optimize event binding (#3512)

This commit is contained in:
neverland 2019-06-14 16:50:37 +08:00 committed by GitHub
parent 6e30dcb1d0
commit c05124b3ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 52 deletions

View File

@ -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
}; };
} }

View File

@ -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()}