大規模なデータを効率的にレンダリング「vue-virtual-collection」
by kabanoki
HTML
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/index.min.js"></script>
<div id="app">
<select v-model="n">
<option value="50">50</option>
<option value="100">100</option>
<option value="150">150</option>
<option value="500">500</option>
<option value="1000">1000</option>
</select>
<virtual-collection
:cell-size-and-position-getter="cellSizeAndPositionGetter"
:collection="items"
:height="500"
:width="680"
>
<div slot="cell" slot-scope="props">{{props.data}}</div>
</virtual-collection>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
CSS
.cell-container{
border: 1px solid #ddd;
justify-content: center;
align-items: center;
display: flex;
}
Vue
const VirtualCollection = window["vue-virtual-collection"].default;
Vue.use(VirtualCollection);
let app = new Vue({
el: '#app',
data: {
n:1000,
items: new Array(1000).fill(0).map((_, index) => ({ data: '#' + index }))
},
methods: {
cellSizeAndPositionGetter(item, index) {
// compute size and position
let min = 100 ;
let max = 150 ;
let random = Math.floor(Math.random() * (max + 1 - min) ) + min ;
return {
width: 100,
height: random,
x: (index % 6) * 110,
y: parseInt(index / 6) * 160
}
}
},
watch: {
n: function(value) {
this.items = new Array(Number(this.n)).fill(0).map((_, index) => ({ data: '#' + index }));
}
}
});