虚拟列表 Vue 组件

虚拟列表不是一个单独的 Vue 组件,而只是 <f7-list><f7-list-item> Vue 组件与 Framework7 特殊的 虚拟列表 组件联合使用的特殊情况。

虚拟列表属性

属性类型默认值描述
<f7-list> 属性
virtual-listbooleanfalse启用虚拟列表
virtual-list-paramsobject带有 虚拟列表参数 的对象

虚拟列表事件

事件描述
<f7-list> 事件
virtual:itembeforeinsert在项添加到虚拟文档片段之前触发事件
virtual:itemsbeforeinsert在移除当前 DOM 列表且插入新文档之前触发事件
virtual:itemsafterinsert在插入带有项的新文档片段之后触发事件
virtual:beforeclear在移除当前 DOM 列表并用新的文档片段替换之前触发事件

示例

此处是带有虚拟列表和搜索栏以搜索虚拟列表项的完整页面示例

virtual-list.vue
<template>
  <f7-page>
    <f7-navbar title="Virtual List">
      <f7-subnavbar :inner="false">
        <f7-searchbar
          search-container=".virtual-list"
          search-item="li"
          search-in=".item-title"
        ></f7-searchbar>
      </f7-subnavbar>
    </f7-navbar>
    <f7-block>
      <p>
        Virtual List allows to render lists with huge amount of elements without loss of
        performance. And it is fully compatible with all Framework7 list components such as Search
        Bar, Infinite Scroll, Pull To Refresh, Swipeouts (swipe-to-delete) and Sortable.
      </p>
      <p>Here is the example of virtual list with 10 000 items:</p>
    </f7-block>
    <f7-list strong outline-ios inset-md dividers-ios class="searchbar-not-found">
      <f7-list-item title="Nothing found"></f7-list-item>
    </f7-list>
    <f7-list
      strong
      outline-ios
      inset-md
      dividers-ios
      class="searchbar-found"
      medial-list
      virtual-list
      :virtual-list-params="{
        items,
        searchAll,
        renderExternal,
        height: theme.ios ? 63 : theme.md ? 73 : 77,
      }"
    >
      <ul>
        <f7-list-item
          v-for="(item, index) in vlData.items"
          :key="index"
          media-item
          link="#"
          :title="item.title"
          :subtitle="item.subtitle"
          :style="`top: ${vlData.topPosition}px`"
          :virtual-list-index="item.index"
        ></f7-list-item>
      </ul>
    </f7-list>
  </f7-page>
</template>
<script>
import {
  f7Navbar,
  f7Page,
  f7List,
  f7ListItem,
  f7Subnavbar,
  f7Searchbar,
  f7Block,
  theme,
} from 'framework7-vue';

export default {
  components: {
    f7Navbar,
    f7Page,
    f7List,
    f7ListItem,
    f7Subnavbar,
    f7Searchbar,
    f7Block,
  },
  data() {
    const items = [];
    for (let i = 1; i <= 10000; i += 1) {
      items.push({
        title: `Item ${i}`,
        subtitle: `Subtitle ${i}`,
        index: i,
      });
    }
    return {
      theme,
      items,
      vlData: {
        items: [],
      },
    };
  },
  methods: {
    searchAll(query, items) {
      const found = [];
      for (let i = 0; i < items.length; i += 1) {
        if (items[i].title.toLowerCase().indexOf(query.toLowerCase()) >= 0 || query.trim() === '')
          found.push(i);
      }
      return found; // return array with mathced indexes
    },
    renderExternal(vl, vlData) {
      this.vlData = vlData;
    },
  },
};
</script>