|
| 1 | + |
| 2 | +<template> |
| 3 | + <div> |
| 4 | + <div class="movies"> |
| 5 | + <div class="movie" v-for="movie in movies" :key="movie.id"> |
| 6 | + <img :src="movie.img"/> |
| 7 | + </div> |
| 8 | + </div> |
| 9 | + <div class="loader" v-if="isLoading"></div> |
| 10 | + <div class="last" v-if="isLast">No more movies 😒</div> |
| 11 | + </div> |
| 12 | +</template> |
| 13 | + |
| 14 | +<script lang="ts"> |
| 15 | +import Vue from "vue"; |
| 16 | +import InfiniteAjaxScroll from '@webcreate/infinite-ajax-scroll'; |
| 17 | +
|
| 18 | +const catalog = [ |
| 19 | + { |
| 20 | + title: "The Matrix", |
| 21 | + img: "https://media-cache.cinematerial.com/p/500x/uq49lqmo/the-matrix-movie-poster.jpg?v=1548664065" |
| 22 | + }, |
| 23 | + { |
| 24 | + title: "Jurrasic Park", |
| 25 | + img: "https://media-cache.cinematerial.com/p/500x/4ubyv2go/jurassic-park-movie-poster.jpg?v=1456328203" |
| 26 | + }, |
| 27 | + { |
| 28 | + title: "Indiana Jones", |
| 29 | + img: "https://cdn.shopify.com/s/files/1/0057/3728/3618/products/609df06d7c2b5fb3125f16a7e4e34152_592ed277-d9d9-4400-af4b-f793370e5f54_480x.progressive.jpg?v=1573616163" |
| 30 | + }, |
| 31 | + { |
| 32 | + title: "2001, A space odyssey", |
| 33 | + img: "https://cdn.shopify.com/s/files/1/1416/8662/products/2001_a_space_odyssey_french_grande_linen_original_film_art_f_1200x.jpg?v=1587685085" |
| 34 | + } |
| 35 | +] |
| 36 | +
|
| 37 | +export default Vue.extend({ |
| 38 | + data() { |
| 39 | + return { |
| 40 | + ias: null, |
| 41 | + isLast: false, |
| 42 | + isLoading: false, |
| 43 | + movies: [] |
| 44 | + }; |
| 45 | + }, |
| 46 | + mounted() { |
| 47 | + const ias = new InfiniteAjaxScroll('.movies', { |
| 48 | + item: '.movie', |
| 49 | + next: this.nextPage, |
| 50 | + spinner: { |
| 51 | + show: () => this.isLoading = true, |
| 52 | + hide: () => this.isLoading = false, |
| 53 | + }, |
| 54 | + }); |
| 55 | +
|
| 56 | + ias.on('last', () => { |
| 57 | + this.isLast = true; |
| 58 | + }); |
| 59 | + }, |
| 60 | + methods: { |
| 61 | + nextPage(pageIndex) { |
| 62 | + const hasNextUrl = pageIndex < 4; |
| 63 | +
|
| 64 | + return Promise.all([ |
| 65 | + this.loadNewMovie(), |
| 66 | + this.loadNewMovie(), |
| 67 | + this.loadNewMovie() |
| 68 | + ]).then(() => hasNextUrl); |
| 69 | + }, |
| 70 | + loadNewMovie() { |
| 71 | + return new Promise((resolve) => { |
| 72 | + // Simulate loading of new movie |
| 73 | + setTimeout(() => { |
| 74 | + const index = Math.round((Math.random() * (catalog.length - 1))); |
| 75 | + const movie = {...catalog[index], id: this.movies.length + 1 }; |
| 76 | +
|
| 77 | + this.movies.push(movie) |
| 78 | + resolve() |
| 79 | + }, 200) |
| 80 | + }) |
| 81 | + } |
| 82 | + } |
| 83 | +}); |
| 84 | +</script> |
| 85 | + |
| 86 | +<style lang="scss" scoped> |
| 87 | + .movies { |
| 88 | + margin: 0 auto; |
| 89 | + padding: 20px; |
| 90 | + max-width: 300px; |
| 91 | + } |
| 92 | + .movie { |
| 93 | + margin-top: 20px; |
| 94 | + padding: 20px; |
| 95 | + background-image: linear-gradient(to right, #EE0979 0%, #F73D39 20%); |
| 96 | + img { |
| 97 | + width: 100%; |
| 98 | + } |
| 99 | + } |
| 100 | +
|
| 101 | + .last { |
| 102 | + font-family: sans-serif; |
| 103 | + text-align: center; |
| 104 | + color: #999; |
| 105 | + line-height: 40px; |
| 106 | + } |
| 107 | +
|
| 108 | + .loader { |
| 109 | + height: 40px; |
| 110 | + background: transparent url('loader.svg') no-repeat center center; |
| 111 | + background-size: 40px 19px; |
| 112 | + animation: flipAnimation 1s infinite; |
| 113 | + } |
| 114 | +
|
| 115 | + @keyframes flipAnimation { |
| 116 | + 0%,100% { transform: rotateY(-180deg); } |
| 117 | + 50% { transform: rotateY(0deg); } |
| 118 | + } |
| 119 | +</style> |
0 commit comments