Virtual List

Virtual List for Large Datasets

A virtual list keeps all items as data but puts only the rows near the viewport in the DOM. You give it an empty list virtual-list element, the items array, a renderItem(item) function that returns one <li>, and a row height; it does the rest as you scroll. The inventory page creates it in $onMounted:

The virtual list of every copy in src/pages/inventory.f7
      vl = $f7.virtualList.create({
        el: $el.value.find('.inventory-list'),
        items: [],
        renderItem,
        height: $f7.theme === 'ios' ? 62 : 54, // measured row heights, in pixels
        searchAll: (query, items) => { // every word must match, like the searchbar's own rule
          const words = query.trim().toLowerCase().split(/\s+/);
          return items.flatMap((c, i) => {
            const text = `${c.title} ${c.author} ${c.condition}`.toLowerCase();
            return words.every((w) => text.includes(w)) ? [i] : [];
          });
        },
      });

The heights were measured from the rendered rows (62 px in iOS, 54 px in Material with these fonts). A wrong fixed height makes rows overlap or leave gaps; pass height: 'auto' or a function per item when rows differ, which costs a measurement per row. appendItems(), replaceAllItems() and deleteItem() change the data. A searchbar whose searchContainer is the list calls searchAll instead of hiding rows, most of which are not in the DOM.