fix(List): may trigger load event repeatedly (#4953)

This commit is contained in:
neverland 2019-11-07 17:30:21 +08:00 committed by GitHub
parent 7fc5fb7f5b
commit 0164c33fa5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 23 deletions

View File

@ -42,6 +42,13 @@ export default createComponent({
} }
}, },
data() {
return {
// use sync innerLoading state to avoid repeated loading in some edge cases
innerLoading: this.loading
};
},
mounted() { mounted() {
if (this.immediateCheck) { if (this.immediateCheck) {
this.check(); this.check();
@ -49,14 +56,17 @@ export default createComponent({
}, },
watch: { watch: {
loading: 'check', finished: 'check',
finished: 'check' loading(val) {
this.innerLoading = val;
this.check();
}
}, },
methods: { methods: {
check() { check() {
this.$nextTick(() => { this.$nextTick(() => {
if (this.loading || this.finished || this.error) { if (this.innerLoading || this.finished || this.error) {
return; return;
} }
@ -89,6 +99,7 @@ export default createComponent({
} }
if (isReachEdge) { if (isReachEdge) {
this.innerLoading = true;
this.$emit('input', true); this.$emit('input', true);
this.$emit('load'); this.$emit('load');
} }
@ -98,6 +109,36 @@ export default createComponent({
clickErrorText() { clickErrorText() {
this.$emit('update:error', false); this.$emit('update:error', false);
this.check(); this.check();
},
genLoading() {
if (this.innerLoading) {
return (
<div class={bem('loading')} key="loading">
{this.slots('loading') || (
<Loading size="16">{this.loadingText || t('loading')}</Loading>
)}
</div>
);
}
},
genFinishedText() {
if (this.finished && this.finishedText) {
return (
<div class={bem('finished-text')}>{this.finishedText}</div>
);
}
},
genErrorText() {
if (this.error && this.errorText) {
return (
<div onClick={this.clickErrorText} class={bem('error-text')}>
{this.errorText}
</div>
);
}
} }
}, },
@ -105,23 +146,11 @@ export default createComponent({
const Placeholder = <div ref="placeholder" class={bem('placeholder')} />; const Placeholder = <div ref="placeholder" class={bem('placeholder')} />;
return ( return (
<div class={bem()} role="feed" aria-busy={this.loading}> <div class={bem()} role="feed" aria-busy={this.innerLoading}>
{this.direction === 'down' ? this.slots() : Placeholder} {this.direction === 'down' ? this.slots() : Placeholder}
{this.loading && ( {this.genLoading()}
<div class={bem('loading')} key="loading"> {this.genFinishedText()}
{this.slots('loading') || ( {this.genErrorText()}
<Loading size="16">{this.loadingText || t('loading')}</Loading>
)}
</div>
)}
{this.finished && this.finishedText && (
<div class={bem('finished-text')}>{this.finishedText}</div>
)}
{this.error && this.errorText && (
<div onClick={this.clickErrorText} class={bem('error-text')}>
{this.errorText}
</div>
)}
{this.direction === 'up' ? this.slots() : Placeholder} {this.direction === 'up' ? this.slots() : Placeholder}
</div> </div>
); );

View File

@ -108,7 +108,7 @@ test('check the case that scroller is not window', async () => {
restoreMock(); restoreMock();
}); });
test('check the direction props', async () => { test('check the direction props', () => {
const wrapper = mount(List, { const wrapper = mount(List, {
slots: { slots: {
default: '<div class="list-item">list item</div>' default: '<div class="list-item">list item</div>'
@ -118,8 +118,6 @@ test('check the direction props', async () => {
} }
}); });
await later();
let children = wrapper.findAll('.van-list > div'); let children = wrapper.findAll('.van-list > div');
expect(children.at(0).is('.van-list__placeholder')).toBeTruthy(); expect(children.at(0).is('.van-list__placeholder')).toBeTruthy();
expect(children.at(1).is('.list-item')).toBeTruthy(); expect(children.at(1).is('.list-item')).toBeTruthy();
@ -129,7 +127,6 @@ test('check the direction props', async () => {
direction: 'down' direction: 'down'
}); });
await later();
children = wrapper.findAll('.van-list > div'); children = wrapper.findAll('.van-list > div');
expect(children.at(0).is('.list-item')).toBeTruthy(); expect(children.at(0).is('.list-item')).toBeTruthy();
expect(children.at(1).is('.van-list__placeholder')).toBeTruthy(); expect(children.at(1).is('.van-list__placeholder')).toBeTruthy();