Vue optimizes long list performance and fuzzy real-time search implementation

1. Open source project address

vue-virtual-scroller

vue-virtual-scroll-list

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

Refer to the official example

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.

Guess you like

Origin blog.csdn.net/weixin_47560078/article/details/127682875