[vue]實做一個快速render的select控制項

  • 1001
  • 0
  • vue
  • 2018-02-21

[vue]實做一個快速render的select控制項

在現有系統中,常有好幾仟甚至上萬筆的資料,需要綁定在select控制項,但是卻遇到了資料量太大,在某些瀏覽器需要等到好幾秒的時間,以chrome為例在不同電腦,有些需要等很久,有些則是很正常,無法排除瀏覽器的問題,那就只好從程式碼來下手,先來看一下我假設的例子

<template>
  <div id="app">
    <select v-model="model">
      <option v-for="item in list" :key="item.id" :value="item.id">
        {{item.name}}
      </option>
    </select>
  </div>
</template>

<script>
export default {
  name: 'App',
  data () {
    return {
      list: [],
      model: 0
    }
  },
  mounted () {
    for (let i = 0; i < 10000; i++) {
      this.list.push({
        id: i, name: 'select' + i
      })
    }
  }
}
</script>

<style>

</style>

以一萬筆來說,至少需要5秒才能綁定,而且因為javascript是單執行緒的問題,整個畫面會卡死不能動,為何會導致這種狀況呢?因為vue 2.0開始使用virtual dom的方式來追蹤整個畫面狀態的改變,這樣會讓畫面在觸發時,re render會很快速,但只要資料筆數太大的話,就無法解決這個問題,所以我們可以操作dom元素和原生javascript來達成快速初始化的需求,下面是example

<template>
  <div id="app">
    <select ref="fastSelect">
    </select>
  </div>
</template>

<script>

export default {
  name: 'App',
  data () {
    return {
      model: 0
    }
  },
  mounted () {
    let options = `<option>please select</option>`
    for (let i = 0; i < 10000; i++) {
      options += `<option value="${i}">select${i}</option>`
    }
    this.$refs.fastSelect.innerHTML = options
  }
}
</script>

<style>

</style>

實際上如果真的要自行包成元件的話,還有很多狀況得顧慮到,所以最後筆者便包成一個共用元件,並直接放到npm上面,如果你只是想要一個可以大量資料並快速初始化的話,就不用再自己刻輪子了,但必須得注意一下此元件在re render的時候,一定會比v-for的方式還要消耗資源哦,所以還是得視自己的需求使用,如果你也遇到了binding select過慢的問題,可以試著使用看看此元件是否能解決您的問題,以下則是github的位址。

https://github.com/kinanson/vue-fast-select