无限滚动,常用于接口数据比较多情况。先加载一部分,滚动到一定位置后再加载一部分,直到所有数据全部加载完毕。
# 基础示例
<template>
<EBlock class="e-infinite-scroll-showcase">
<EBlock style="margin: 0 10px;">
<EText>1. 预查1屏,当前行数{{ count1 }},查询接口非常快(5/1ms)</EText>
</EBlock>
<EInfiniteScroll style="height: 200px; width: 500px; border: 1px solid #aaa; margin: 10px;"
@more="loadMore(1, 'count1')">
<EBlock v-for="i in count1" :key="i"
style="height: 30px; width: 100%; background: #ddd; margin: 5px 0;">
<EText>{{ i }}</EText>
</EBlock>
</EInfiniteScroll>
</EBlock>
</template>
<script>
export default {
data() {
return {
count1: 10,
};
},
created() {
console.warn('count1 自动加载 0 次,全部加载完应调用 9 次');
},
methods: {
async loadMore(sleepTime, countPropName, total = 50) {
console.log(`>>> calling ${countPropName}`);
await sleep(sleepTime);
this[countPropName] = Math.min(this[countPropName] + 5, total);
},
},
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
</script>
# 查询接口时间
如果查询接口在 16ms 内,则不会产生 loading 状态。
<template>
<EBlock class="e-infinite-scroll-showcase">
<EBlock style="margin: 0 10px;">
<EText>2. 预查1屏,当前行数{{ count2 }},查询接口比较慢(5/100ms)</EText>
</EBlock>
<EInfiniteScroll style="height: 200px; width: 500px; border: 1px solid #aaa; margin: 10px;"
@more="loadMore(100, 'count2')">
<EBlock v-for="i in count2" :key="i"
style="height: 30px; width: 100%; background: #ddd; margin: 5px 0;">
<EText>{{ i }}</EText>
</EBlock>
<EBlock slot="loading" style="height: 50px;" align="center">
<ESpinnerPie size="30" />
</EBlock>
<EBlock slot="message" style="height: 40px;" align="center" background="background">
<EText color="faded">我们是有底线的。</EText>
</EBlock>
</EInfiniteScroll>
<EBlock style="margin: 0 10px;">
<EText>3. 预查1屏,当前行数{{ count3 }},查询接口比较慢(5/2s)</EText>
</EBlock>
<EInfiniteScroll style="height: 200px; width: 500px; border: 1px solid #aaa; margin: 10px;"
offset="1" @more="loadMore(2000, 'count3')">
<EBlock v-for="i in count3" :key="i"
style="height: 30px; width: 100%; background: #ddd; margin: 5px 0;">
<EText>{{ i }}</EText>
</EBlock>
<EBlock slot="loading" style="height: 50px;" align="center">
<ESpinnerPie size="30" />
</EBlock>
<EBlock slot="message" style="height: 40px;" align="center" background="background">
<EText color="faded">我们是有底线的。</EText>
</EBlock>
</EInfiniteScroll>
</EBlock>
</template>
<script>
export default {
data() {
return {
count2: 10,
count3: 10,
};
},
created() {
console.warn('count2 自动加载 0 次,全部加载完应调用 9 次');
console.warn('count3 自动加载 0 次,全部加载完应调用 9 次');
},
methods: {
async loadMore(sleepTime, countPropName, total = 50) {
console.log(`>>> calling ${countPropName}`);
await sleep(sleepTime);
this[countPropName] = Math.min(this[countPropName] + 5, total);
},
},
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
</script>
# 不滚动就开始查
设置 immediate
属性,一旦加载立即调用查询接口。
<template>
<EBlock class="e-infinite-scroll-showcase">
<EBlock style="margin: 0 10px;">
<EText>4. 预查1屏,当前行数{{ count4 }},立即查询(不滚动就开始查)</EText>
</EBlock>
<EInfiniteScroll style="height: 200px; width: 500px; border: 1px solid #aaa; margin: 10px;"
immediate @more="loadMore(1000, 'count4')">
<EBlock v-for="i in count4" :key="i"
style="height: 30px; width: 100%; background: #ddd; margin: 5px 0;">
<EText>{{ i }}</EText>
</EBlock>
</EInfiniteScroll>
<EBlock style="margin: 0 10px;">
<EText>5. 预查1屏,当前行数{{ count5 }},立即查询(不滚动就开始查),总数不满一屏</EText>
</EBlock>
<EInfiniteScroll style="height: 200px; width: 500px; border: 1px solid #aaa; margin: 10px;"
immediate @more="loadMore(1000, 'count5', 3)">
<EBlock v-for="i in count5" :key="i"
style="height: 30px; width: 100%; background: #ddd; margin: 5px 0;">
<EText>{{ i }}</EText>
</EBlock>
</EInfiniteScroll>
</EBlock>
</template>
<script>
export default {
data() {
return {
count4: 5,
count5: 2,
};
},
created() {
console.warn('count4 自动加载 1 次,全部加载完应调用 10 次');
console.warn('count5 自动加载 2 次,全部加载完应调用 2 次');
},
methods: {
async loadMore(sleepTime, countPropName, total = 50) {
console.log(`>>> calling ${countPropName}`);
await sleep(sleepTime);
this[countPropName] = Math.min(this[countPropName] + 5, total);
},
},
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
</script>
# 没有加载更多函数
不设置 more
的情况。
<template>
<EBlock class="e-infinite-scroll-showcase">
<EBlock style="margin: 0 10px;">
<EText>6. 当前行数{{ count6 }},无加载更多函数</EText>
</EBlock>
<EInfiniteScroll style="height: 200px; width: 500px; border: 1px solid #aaa; margin: 10px;">
<EBlock v-for="i in count6" :key="i"
style="height: 30px; width: 100%; background: #ddd; margin: 5px 0;">
<EText>{{ i }}</EText>
</EBlock>
</EInfiniteScroll>
</EBlock>
</template>
<script>
export default {
data() {
return {
count6: 10,
};
},
created() {
console.warn('count6 自动加载 0 次,全部加载完应调用 0 次');
},
};
</script>
# 预查多屏数据
通过设置 offset
属性。
<template>
<EBlock class="e-infinite-scroll-showcase">
<EBlock style="margin: 0 10px;">
<EText>7. 预查4屏,当前行数{{ count7 }},查询接口比较慢(5/5s)</EText>
</EBlock>
<EInfiniteScroll style="height: 200px; width: 500px; border: 1px solid #aaa; margin: 10px;"
offset="4" @more="loadMore(5000, 'count7')">
<EBlock v-for="i in count7" :key="i"
style="height: 30px; width: 100%; background: #ddd; margin: 5px 0;">
<EText>{{ i }}</EText>
</EBlock>
<EBlock slot="loading" style="height: 50px;" align="center">
<ESpinnerPie size="30" />
</EBlock>
<EBlock slot="message" style="height: 40px;" align="center" background="background">
<EText color="faded">我们是有底线的。</EText>
</EBlock>
</EInfiniteScroll>
</EBlock>
</template>
<script>
export default {
data() {
return {
count7: 10,
};
},
created() {
console.warn('count7 自动加载 0 次,全部加载完应调用 9 次');
},
methods: {
async loadMore(sleepTime, countPropName, total = 50) {
console.log(`>>> calling ${countPropName}`);
await sleep(sleepTime);
this[countPropName] = Math.min(this[countPropName] + 5, total);
},
},
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
</script>
# 数据总数为0的情况
接口返回数据为 0 时,组件的展示情况。
<template>
<EBlock class="e-infinite-scroll-showcase">
<EInfiniteScroll style="height: 200px; width: 500px; border: 1px solid #aaa; margin: 10px;"
immediate @more="loadMore(1000, 'count8', 0)">
<EBlock v-for="i in count8" :key="i"
style="height: 30px; width: 100%; background: #ddd; margin: 5px 0;">
<EText>{{ i }}</EText>
</EBlock>
</EInfiniteScroll>
</EBlock>
</template>
<script>
export default {
data() {
return {
count8: 0,
};
},
created() {
console.warn('count8 自动加载 1 次,全部加载完应调用 1 次');
},
methods: {
async loadMore(sleepTime, countPropName, total = 50) {
console.log(`>>> calling ${countPropName}`);
await sleep(sleepTime);
this[countPropName] = Math.min(this[countPropName] + 5, total);
},
},
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
</script>
# 滚动到指定位置
通过调用组件的 scrollTo
方法让内容滚动到指定位置。
<template>
<EBlock class="e-infinite-scroll-showcase">
<EButton style="margin: 0 0 10px 10px;"
@click="()=>$refs.scroll.scrollTo({top: 200, behavior: 'smooth'})">
滚动到第6行
</EButton>
<EInfiniteScroll ref="scroll" style="height: 200px; width: 500px; border: 1px solid #aaa; margin: 10px;"
@more="loadMore(9, 'count9')">
<EBlock v-for="i in count9" :key="i"
style="height: 30px; width: 100%; background: #ddd; margin: 5px 0;">
<EText>{{ i }}</EText>
</EBlock>
</EInfiniteScroll>
</EBlock>
</template>
<script>
export default {
data() {
return {
count9: 10,
};
},
created() {
console.warn('count9 自动加载 0 次,全部加载完应调用 9 次');
},
methods: {
async loadMore(sleepTime, countPropName, total = 50) {
console.log(`>>> calling ${countPropName}`);
await sleep(sleepTime);
this[countPropName] = Math.min(this[countPropName] + 5, total);
},
},
};
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
</script>
# EInfiniteScroll
# Props
Name | Description | Type | Required | Default |
---|---|---|---|---|
offset | bar 底部跟显示区域(一屏)底部的距离差,在多少以内需要加载更多。1-9 表示页数,10 以上表示像素 | String / Number | false | 1 |
immediate | 是否在一开始就立即检查是否要加载更多 | Boolean | false | - |
# Slots
Name | Description | Default Slot Content |
---|---|---|
default | - | - |
loading | - | - |
message | - | - |