2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-05-17 02:29:37 +03:00
Files
vue-select/docs/components/InfiniteScroll.vue
T
Jeff Sagal ae2eb99f86 wip
2021-07-28 15:56:54 -07:00

75 lines
1.7 KiB
Vue

<template>
<v-select
:options="paginated"
:filterable="false"
@open="onOpen"
@close="onClose"
@search="(query) => (search = query)"
>
<template #list-footer>
<li ref="load" class="loader" v-show="hasNextPage">
Loading more options...
</li>
</template>
</v-select>
</template>
<script>
import countries from "../assets/data/countries.js";
export default {
name: "InfiniteScroll",
data: () => ({
observer: null,
limit: 10,
search: "",
}),
mounted() {
/**
* You could do this directly in data(), but since these docs
* are server side rendered, IntersectionObserver doesn't exist
* in that environment, so we need to do it in mounted() instead.
*/
this.observer = new IntersectionObserver(this.infiniteScroll);
},
computed: {
filtered() {
return countries.filter((country) => country.includes(this.search));
},
paginated() {
return this.filtered.slice(0, this.limit);
},
hasNextPage() {
return this.paginated.length < this.filtered.length;
},
},
methods: {
async onOpen() {
if (this.hasNextPage) {
await this.$nextTick();
this.observer.observe(this.$refs.load);
}
},
onClose() {
this.observer.disconnect();
},
async infiniteScroll([{ isIntersecting, target }]) {
if (isIntersecting) {
const ul = target.offsetParent;
const scrollTop = target.offsetParent.scrollTop;
this.limit += 10;
await this.$nextTick();
ul.scrollTop = scrollTop;
}
},
},
};
</script>
<style scoped>
.loader {
text-align: center;
color: #bbbbbb;
}
</style>