Vue

by ivansafonov

HTML

<script src="https://unpkg.com/[email protected]/dist/list-scroller.min.js"></script>
<div id="app">
  <list-scroller :item-component="item" :items-data="items" :item-height="350" class="list" @bottom="addMore" />
</div>

<template id="list-item">
  <div class="item">
    <img :src="imgUrl" />
    <div>
      <h1><b>Item {{ index }}</b></h1>
      {{ ' ' + data.text }}
    </div>
  </div>
</template>

SCSS

.item {
  margin: 1.1em;
  padding: 1em;
  border: solid;
  border-width: 3px;

  img {
    width: 100%;
    max-height: 200px;
    object-fit: contain;
  }
  h1 { 
    font-size: 1.5em; 
  } 
}

Vue

Vue.component('list-item', {
  template: '#list-item',
  props: {
    data: Object,
    index: Number,
  },
  computed: {
    imgUrl() {
      return `https://picsum.photos/id/${this.data.img}/500/200`
    },
  },
});

const lorem =
  'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' +
  'Phasellus mattis at neque eu venenatis. Nam et sodales purus. ' +
  'Suspendisse pulvinar nisl purus, vel consequat neque varius vel. ' +
  'Ut ut consequat lorem. Nulla odio arcu, porta eu fringilla id, ' +
  'porta eget massa. Vivamus porta pulvinar ex, vel egestas erat ' +
  'rutrum vitae. Cras at felis malesuada, lacinia nulla non, ' +
  'tincidunt ligula. Sed facilisis mauris et metus commodo, ' +
  'sit amet porttitor mi efficitur. Cras et accumsan eros. Ut ' +
  'facilisis venenatis quam a luctus. Nam egestas dignissim viverra. ' +
  'Curabitur volutpat, enim et luctus faucibus, ex nisl ultrices est, ' +
  'in faucibus sapien libero vel arcu. Nullam placerat, mauris id ' +
  'vestibulum sollicitudin, lacus leo finibus mauris, nec efficitur ' +
  'neque ex sit amet arcu'

new Vue({
  el: "#app",
  data: { 
      items: [],
      item: Vue.component('list-item'),
  },
  methods: {
    addMore() {
      if (this.items.length > 10000) return

      for (let i = 0; i < 30; i++) {
        this.items.push({
          text: lorem.slice(0, 200 + Math.floor(Math.random() * 500)) + ' ...',
          img: Math.floor(Math.random() * 1000),
        })
      }
    },
  },
  created() {
    this.addMore()
  },
})