2017-09-03 33 views
0

我有100多個項目和呈現需要太多時間的列表。我想只顯示一次可見的內容,然後依次滾動。vue.js - 在可見時動態呈現滾動項目

什麼是最好的方法?

我在下面有這個片段,但vue.set()不起作用。

var dbItems = [{name: 'New item'}, {name:'Another'}, {name:'Third'}]; 
 

 
var app = new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    // if I put items : dbItems, then for some reason the Vue.set() doesn't work!! 
 
    items : [], 
 
    }, 
 
    methods: { 
 
    init: function() { 
 
     this.items = dbItems; // we add all items 
 
    }, 
 
    makeItemVisible : function(id) { 
 
     console.log("Making visible #"+id); 
 
     this.items[id].show = 1; 
 
     Vue.set(this.items, id, this.items[id]); 
 
    } 
 
    } 
 
}); 
 

 
app.init(); 
 
app.makeItemVisible(1); // this works 
 

 
$(document).on('scroll', function(){ 
 
    // function to show elements when visible 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.26/vue.min.js"></script> 
 

 
<div id="app" v-cloak> 
 

 
<button v-on:click="makeItemVisible(0)">MAKE VISIBLE - This button doesn't work</button> 
 

 
    <div class="items" v-show="items.length"> 
 
    <!-- I dont know why, but (key, item) had to be switched compared to VUE documentation! --> 
 
\t <div v-for="(key, item) in items"> 
 
     <div v-if="item.show" style="border:2px solid green;height:700px"> 
 
      You can see me: {{ item.name }} | ID: {{ key }} 
 
     </div> 
 
     <div class="item-blank" data-id="{{ key }}" v-else style="border:2px solid red;height:700px"> 
 
     {{ item.name }} invisible {{ key }} 
 
     </div> 
 
\t \t </div> 
 
    </div> 
 

 
</div>

+2

也許看看那些已經在做這樣的庫,例如[這一個](https://github.com/Akryum/vue-virtual-scroller)。一般來說,這個功能稱爲虛擬滾動。 – poke

回答

0

解決。

編輯:此Vue.js僅適用於Chrome ...否則它非常慢(Firefox最慢),它在一次加載整個HTML文檔時效果更好。

var dbItems = [{name: 'New item'}, {name:'Another'}, {name:'Third'}]; 
 

 
var app = new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    items : dbItems 
 
    }, 
 
    methods: { 
 
    makeItemVisible : function(id) { 
 
     console.log("Making visible #"+id); 
 
     Vue.set(this.items[id], 'show', 1); 
 
    } 
 
    } 
 
}); 
 

 
function isScrolledIntoView(elem) 
 
{ 
 
    var docViewTop = $(window).scrollTop(); 
 
    var docViewBottom = docViewTop + $(window).height(); 
 
    var elemTop = $(elem).offset().top; 
 
    var elemBottom = elemTop + $(elem).height(); 
 
    return (elemTop <= docViewBottom && elemTop >= docViewTop) || (elemBottom >= docViewTop && elemBottom <= docViewBottom); 
 
} 
 

 
var fn = function(){ 
 
    $('.item-blank').each(function(){ 
 
    if(isScrolledIntoView(this)) { 
 
     app.makeItemVisible($(this).attr('data-id')); 
 
    } 
 
    }); 
 
}; 
 
$(window).scroll(fn); 
 
fn(); // because trigger() doesn't work
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.min.js"></script> 
 

 
<div id="app" v-cloak> 
 
    <div class="items" v-show="items.length"> 
 
\t <div v-for="(item, index) in items"> 
 
     <div v-if="item.show" style="border:2px solid green;height:700px"> 
 
      You can see me: {{ item.name }} | ID: {{ index }} 
 
     </div> 
 
     <div class="item-blank" :data-id="index" v-else style="border:2px solid red;height:700px;position:relative;"> 
 
     {{ item.name }} invisible {{ index }} 
 
     </div> 
 
\t \t </div> 
 
    </div> 
 

 
</div>