虛擬清單
虛擬清單允許在不損失效能的情況下,渲染包含大量元素的清單。且與所有 Framework7 元件完全相容,這些元件可與清單搭配使用,例如搜尋欄、無限捲動、下拉更新、滑動刪除和可排序。
虛擬清單版面
虛擬清單 HTML 版面相當簡單,與一般 清單檢視 幾乎相同,只有一個差異:您需要將其留空
<!-- Virtual List -->
<div class="list virtual-list">
<!-- keep it empty -->
</div>
其中
virtual-list
- 使用虛擬清單的任何清單區塊上,所需的附加類別
虛擬清單應用程式方法
現在,當我們有清單的 HTML 時,我們需要初始化它。我們需要使用必要的應用程式方法
app.virtualList.create(parameters)- 使用參數初始化虛擬清單
- parameters - 物件 - 包含虛擬清單參數的物件。必要。
- 方法會傳回已初始化的虛擬清單執行個體
app.virtualList.destroy(el)- 銷毀虛擬清單執行個體
- el - HTMLElement 或 字串(含 CSS 選擇器)或 物件。要銷毀的虛擬清單元素或虛擬清單執行個體。
app.virtualList.get(el)- 透過 HTML 元素取得虛擬清單執行個體
- el - HTMLElement 或 字串(含 CSS 選擇器)。虛擬清單元素。
方法會傳回虛擬清單的執行個體
請注意,虛擬清單容器(清單區塊元素)應在初始化時位於 DOM 中。
虛擬清單參數
讓我們看看所有可用參數的清單
參數 | 類型 | 預設值 | 說明 |
---|---|---|---|
el | HTMLElement 字串 | 目標清單區塊元素。如果是 字串 - 清單區塊元素的 CSS 選擇器 | |
ul | HTMLElement 字串 | 清單區塊內的清單元素 <ul> 。 | |
createUl | 布林值 | true | 會在虛擬清單區塊內自動建立 <ul> 元素。如果停用,則虛擬清單可以在沒有 ul > li 結構的任何區塊元素上使用 |
items | 陣列 | 帶有清單項目的陣列 | |
rowsBefore | 數字 | 在目前螢幕捲動位置之前要呈現的列數 (項目) 數量。預設值等於適合螢幕的列數 (項目) 數量的兩倍 | |
rowsAfter | 數字 | 在目前螢幕捲動位置之後要呈現的列數 (項目) 數量。預設值等於適合螢幕的列數 (項目) 數量 | |
cols | 數字 | 1 | 每列的項目數量。在使用具有動態高度的虛擬清單時不相容 |
height | 數字或函式 (項目) 或「自動」 | 如果是 如果是 如果是 | |
renderItem | 函式 (項目) | 此選用函式允許使用自訂函式來呈現項目 HTML。它可以用於取代 範本 參數 | |
renderExternal | 函式 (vl, renderParameters) | 此選用函式允許使用一些自訂方法來呈現 DOM 項目。在與 Vue/React 外掛程式搭配使用時很有用,可將 DOM 呈現和操作傳遞給 Vue/React。renderParameters 包含具有下列屬性的物件:fromIndex 、toIndex 、listHeight 、topPosition 、items | |
emptyTemplate | 字串 | 如果傳遞空資料,則定義清單項目範本 | |
dynamicHeightBufferSize | 數字 | 1 | 此參數允許控制具有動態高度的虛擬清單 (當 height 參數為函式時) 的緩衝區大小,作為緩衝區大小乘數 |
cache | 布林值 | true | 停用或啟用已呈現清單項目的 DOM 快取。在此情況下,每個項目只會呈現一次,所有後續操作都將使用 DOM 元素。如果您的清單項目有一些使用者互動元素 (例如表單元素或滑動刪除),或可能會修改,則這很有用 |
updatableScroll | 布林值 | 目前裝置是否在捲動期間更新和處理捲動事件。預設值 (如果未指定) 為 iOS 版本低於 8 的所有 iOS 裝置的「false」 | |
setListHeight | 布林值 | true | 如果啟用,則會在清單區塊上設定高度 |
showFilteredItemsOnly | 布林值 | false | 僅顯示由 |
scrollableParentEl | HTMLElement 字串 | 虛擬清單的可捲動父項。如果未指定,則會尋找父項 <div class="page-content"> 元素 | |
搜尋列 | |||
searchByItem | 函式 (查詢、項目、索引) | 會由 搜尋列 使用的搜尋函式,它會接收搜尋查詢、項目本身和項目索引。如果項目與搜尋查詢相符,您需要傳回 true ,否則此函式應傳回 false | |
searchAll | function(query, items) | 由 Searchbar 使用的搜尋功能,它接收搜尋查詢和包含所有項目的陣列。您需要逐項迴圈並傳回已配對項目的索引陣列 |
虛擬清單方法和屬性
因此,要建立虛擬清單,我們必須呼叫
var virtualList = app.virtualList.create({ /* parameters */ })
初始化虛擬清單後,我們在變數中擁有其初始化的執行個體(例如上方範例中的 virtualList
變數),其中包含有用的方法和屬性
屬性 | |
---|---|
virtualList.items | 包含項目的陣列 |
virtualList.filteredItems | 包含已過濾項目的陣列(使用「.filterItems」方法後) |
virtualList.domCache | 包含快取 DOM 項目的物件 |
virtualList.params | 在清單初始化時傳遞的參數 |
virtualList.el | 虛擬清單目標清單區塊元素 |
virtualList.$el | 目標清單區塊元素的 Dom7 執行個體 |
virtualList.pageContentEl | 父層「page-content」元素 |
virtualList.$pageContentEl | 父層「page-content」元素的 Dom7 執行個體 |
virtualList.currentFromIndex | 目前第一個已呈現項目的索引號碼 |
virtualList.currentToIndex | 目前最後一個已呈現項目的索引號碼 |
virtualList.reachEnd | 布林值屬性。如果目前最後一個已呈現項目是所有指定項目的最後一個項目,則等於 true |
方法 | |
virtualList.filterItems(indexes); | 透過傳遞包含要顯示項目的索引陣列來過濾虛擬清單 |
virtualList.resetFilter(); | 停用過濾器並再次顯示所有項目 |
virtualList.appendItem(item); | 將項目附加到虛擬清單 |
virtualList.appendItems(items); | 將包含項目的陣列附加到虛擬清單 |
virtualList.prependItem(item); | 將項目前置到虛擬清單 |
virtualList.prependItems(items); | 將包含項目的陣列前置到虛擬清單 |
virtualList.replaceItem(index, item); | 使用新的項目取代指定索引處的項目 |
virtualList.replaceAllItems(items); | 使用新項目的陣列取代所有項目 |
virtualList.moveItem(oldIndex, newIndex); | 將虛擬項目從 oldIndex 移動到 newIndex |
virtualList.insertItemBefore(index, item); | 在具有指定索引的項目之前插入新項目 |
virtualList.deleteItem(index); | 刪除指定索引處的項目 |
virtualList.deleteItems(indexes); | 刪除指定索引陣列中的項目 |
virtualList.deleteAllItems(); | 刪除所有項目 |
virtualList.clearCache(); | 清除虛擬清單快取的 DOM 元素 |
virtualList.destroy(); | 銷毀已初始化的虛擬清單並移除所有事件 |
virtualList.update(); | 更新虛擬清單,包括重新計算清單大小和重新呈現虛擬清單 |
virtualList.scrollToItem(index); | 根據索引號碼將虛擬清單捲動到指定項目 |
虛擬清單事件
虛擬清單會在應用程式和虛擬清單實例中觸發以下事件
虛擬清單實例會在自身實例和應用程式實例中發出事件。應用程式實例事件名稱相同,但前面加上 vl
。
事件 | 目標 | 引數 | 說明 |
---|---|---|---|
itemBeforeInsert | virtualList | virtualList、itemEl、item | 在項目新增到虛擬文件片段之前觸發事件 |
vlItemBeforeInsert | app | ||
itemsBeforeInsert | virtualList | virtualList、fragment | 在移除目前的 DOM 清單並插入新文件之前觸發事件 |
vlItemsBeforeInsert | app | ||
beforeClear | virtualList | virtualList、fragment | 在移除目前的 DOM 清單並用新的文件片段取代之前觸發事件 |
vlBeforeClear | app | ||
itemsAfterInsert | virtualList | virtualList、fragment | 在插入包含項目的新文件片段之後觸發事件 |
vlItemsAfterInsert | app |
範例
virtual-list.html
<template>
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner sliding">
<div class="title">Virtual List</div>
<div class="subnavbar">
<form data-search-container=".virtual-list" data-search-item="li" data-search-in=".item-title"
class="searchbar searchbar-init">
<div class="searchbar-inner">
<div class="searchbar-input-wrap">
<input type="search" placeholder="Search" />
<i class="searchbar-icon"></i>
<span class="input-clear-button"></span>
</div>
<span class="searchbar-disable-button">Cancel</span>
</div>
</form>
</div>
</div>
</div>
<div class="searchbar-backdrop"></div>
<div class="page-content">
<div class="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>
</div>
<div class="list list-strong list-outline-ios inset-md list-dividers-ios links-list">
<ul>
<li>
<a href="/virtual-list-vdom/">Virtual List VDOM</a>
</li>
</ul>
</div>
<div class="list list-strong list-outline-ios inset-md list-dividers-ios simple-list searchbar-not-found">
<ul>
<li>Nothing found</li>
</ul>
</div>
<div class="list list-strong list-outline-ios inset-md list-dividers-ios virtual-list media-list searchbar-found">
</div>
</div>
</div>
</template>
<script>
export default (props, { $f7, $el, $theme, $onMounted, $onBeforeUnmount }) => {
let items = [];
let virtualList;
for (let i = 1; i <= 10000; i++) {
items.push({
title: 'Item ' + i,
subtitle: 'Subtitle ' + i
});
}
$onMounted(() => {
virtualList = $f7.virtualList.create({
// List Element
el: $el.value.find('.virtual-list'),
// Pass array with items
items,
// Custom search function for searchbar
searchAll: function (query, items) {
var found = [];
for (var i = 0; i < items.length; i++) {
if (items[i].title.toLowerCase().indexOf(query.toLowerCase()) >= 0 || query.trim() === '') found.push(i);
}
return found; //return array with mathced indexes
},
// List item render
renderItem(item) {
return `
<li>
<a class="item-link item-content">
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">${item.title}</div>
</div>
<div class="item-subtitle">${item.subtitle}</div>
</div>
</a>
</li>`;
},
// Item height
height: $theme.ios ? 65 : 69,
});
});
$onBeforeUnmount(() => {
virtualList.destroy()
});
return $render;
}
</script>