1. Open source project address
2. Application scenarios
Optimize long or infinite list performance
3. Principle
Windowed rendering only needs to render a small amount of valid data, reducing the time of creating DOM nodes and re-rendering components.
4. Usage examples
1. Create a Vue project
vue create demo
[Note] The vue2.x project created here using scaffolding.
2. Install through NPM
npm install vue-virtual-scroll-list --save
3. Main.js introduces components
import Vue from 'vue'
import App from './App.vue'
import VirtualList from 'vue-virtual-scroll-list'
Vue.component('virtual-list', VirtualList)
Vue.config.productionTip = false
new Vue({
render: h => h(App)
}).$mount('#app')
[Note] The sliding window component needs to be introduced globally here, otherwise there is no way to parse the component label in App.vue.
4. data.js simulates generated data
let idCounter = 0
export function getData(count) {
const data = []
for (let index = 0; index < count; index++) {
data.push({
id: String(idCounter++),
text: Math.random()
.toString(16)
.substr(10)
})
}
return data
}
data is an array of objects, each object includes id and text field attributes, and text is generated by a random function.
5. Item component
<template>
<div class="item">
<div class="id">{
{ source.id }} - {
{ source.text }}</div>
</div>
</template>
<script>
export default {
name: 'item-component',
props: {
source: {
type: Object,
default() {
return {}
}
}
}
}
</script>
<style scoped>
.item {
display: flex;
flex-direction: column;
border-bottom: 1px solid lightgrey;
padding: 1em;
}
</style>
The Item component is used to render each item.
6. App.vue reference component
<template>
<div id="app">
<div class="wrapper">
<virtual-list class="list" style="height: 360px; overflow-y: auto;" :data-key="'id'" :data-sources="items"
:data-component="item" :estimate-size="50" />
</div>
</div>
</template>
<script>
import Item from './Item'
import { getData } from './data'
export default {
name: 'App',
data() {
return {
item: Item,
items: getData(1000)
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 1em;
padding: 1em;
}
.list {
border: 2px solid steelblue;
border-radius: 3px;
}
</style>
Create a sliding window and render a thousand pieces of data.
7. Test effect
npm run serve
Rendering a thousand pieces of data is very smooth.
5. Implementation of real-time fuzzy search
1. Implementation principle
Regular matching between dataset and keyword keyword
2. App.vue code modification
Add a new input box, monitor the input content in real time, and then search the input content as a keyword in the dataset. If it meets the regular matching relationship, the data will be saved in the result set resultArray, and finally returned to the sliding window for rendering.
<template>
<div id="app">
<div class="wrapper">
<!-- 输入框 -->
<input type="text" placeholder="请输入关键字" v-model="inputVal" @input="initSearchList" value=""
class="searcher-text" />
<!-- 动态滑动窗口 -->
<virtual-list class="list" style="height: 360px; overflow-y: auto;" :data-key="'id'" :data-sources="items"
:data-component="item" :estimate-size="50" />
</div>
</div>
</template>
<script>
import Item from './Item'
import { getData } from './data'
export default {
name: 'App',
data() {
return {
item: Item,
items: [],
allDataSet: getData(1000),
inputVal: ''
}
},
mounted() {
this.items = this.allDataSet;
},
methods: {
// 捕获输入关键字,动态渲染滑动串口内容
initSearchList() {
const keyword = this.inputVal;
this.items = this.searchKeywordsByRegExp(keyword,this.allDataSet);
},
// 从 dataset 中匹配 keyword
searchKeywordsByRegExp(keyword, dataset) {
if (!(dataset instanceof Array)) {
return [];
}
var len = dataset.length;
var resultArray = [];
var reg = new RegExp(keyword);
for (var i = 0; i < len; i++) {
// 如果字符串中不包含目标字符会返回-1
if (dataset[i]['text'].match(reg)) {
resultArray.push(dataset[i]);
}
}
return resultArray;
}
},
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 1em;
padding: 1em;
}
.list {
border: 2px solid steelblue;
border-radius: 3px;
}
.searcher-text {
width: 99%;
height: 28px;
margin-bottom: 10px;
border: 2px solid steelblue;
border-radius: 3px;
}
</style>
3. Effect test
It can be seen that fuzzy matching can be achieved by matching ab in 1000 pieces of data. The higher the accuracy, the precise matching will be achieved.