observerInfiniteScroll.vue
<template> <div> <ul> <li class="list-item" v-for="item in items" :key="item.id">{{item.title}}</li> </ul> <Observer @intersect="intersected" /> </div> </template> <script> import Observer from 'src/components/observer/observer'; import axios from 'axios'; export default { data: () => ({ page: 1, items: [] }), components: { Observer, }, methods: { async intersected() { await axios .get('https://cnodejs.org/api/v1/topics', { params: { page: this.page, limit: 20, }, }) .then(res => { this.page++; this.items = [...this.items, ...res.data.data]; }); }, }, }; </script> <style lang="scss"> .list-item { padding: 0.3rem; } </style>
observer.vue
<template> <div class="observer" /> </template> <script> export default { props: ['options'], data: () => ({ observer: null }), mounted() { const options = this.options || {}; this.observer = new IntersectionObserver(([entry]) => { if (entry && entry.isIntersecting) { this.$emit('intersect'); } }, options); this.observer.observe(this.$el); }, destroyed() { this.observer.disconnect(); }, }; </script>
.