我目前正在学习将laravel与vue相结合。此页面应从服务器获取发布数据并显示在用户时间线中。我成功获取所有数据并显示它。但我想实现无限卷轴,但我不知道该怎么做。我曾经尝试过许多不同的方式也没有工作。也许我对vue的了解仍然很新鲜。对我有什么建议吗?
以下是我的原始代码:jsfiddle
以下是我尝试使用此example实现无限滚动的代码。
滚动符号显示但似乎数组没有通过,数据仍然一次显示。
提交/feed
后,服务器将返回包含帖子信息的数组。但我不知道如何传入列表数组。
返回数组
答案 0 :(得分:16)
安装:
npm install vue-infinite-scroll --save
在main.js中注册:
// register globally
var infiniteScroll = require('vue-infinite-scroll');
Vue.use(infiniteScroll)
// or for a single instance
var infiniteScroll = require('vue-infinite-scroll');
new Vue({
directives: {infiniteScroll}
})
你的HTML:
<div v-infinite-scroll="loadMore" infinite-scroll-disabled="busy" infinite-scroll-distance="10">
...
</div>
你的组成部分:
var count = 0;
new Vue({
el: '#app',
data: {
data: [],
busy: false
},
methods: {
loadMore: function() {
this.busy = true;
setTimeout(() => {
for (var i = 0, j = 10; i < j; i++) {
this.data.push({ name: count++ });
}
this.busy = false;
}, 1000);
}
}
});
答案 1 :(得分:2)
一种解决方案是设置锁定机制以停止对后端的快速请求。在发出请求之前将启用锁定,然后在完成请求并使用新内容(扩展页面大小)更新DOM时,将禁用锁定。
例如:
new Vue({
// ... your Vue options.
ready: function () {
var vm = this;
var lock = true;
window.addEventListener('scroll', function () {
if (endOfPage() && lock) {
vm.$http.get('/myBackendUrl').then(function(response) {
vm.myItems.push(response.data);
lock = false;
});
};
});
}; });
要记住的另一件事是滚动事件的触发次数比您真正需要的要多(特别是在移动设备上),您可以限制此事件以提高性能。这可以通过requestAnimationFrame有效地完成:
;(function() {
var throttle = function(type, name, obj) {
obj = obj || window;
var running = false;
var func = function() {
if (running) { return; }
running = true;
requestAnimationFrame(function() {
obj.dispatchEvent(new CustomEvent(name));
running = false;
});
};
obj.addEventListener(type, func);
};
/* init - you can init any event */
throttle ("scroll", "optimizedScroll");
})();
// handle event
window.addEventListener("optimizedScroll", function() {
console.log("Resource conscious scroll callback!");
});
答案 2 :(得分:1)
我也尝试了Vue-infinite-scroll,但在与Vue-router对齐时,至少在我的代码中,它无法正常工作。 所以我想出了自己的解决方案。
<template>
<div ref="loadmore" class="infinite-container">
<!-- the inifite container -->
</div>
</template>
<script>
export default {
data() {
return {
timer: null,
// check if is in infinite procees
busy: false
}
},
methods: {
infiniteScrollHandler() {
//check if container's bttom is overflow screen
let bottomOff =
this.$refs.loadmore.getBoundingClientRect().bottom - screen.height;
if (bottomOff < 10 && !this.busy) {
console.log("loading... " + new Date());
this.busy = true;
// do something
this.busy = false;
}
},
setIntervalTimer() {
//check every 500 milliseconds
this.timer = setInterval(() => {
this.infiniteScrollHandler();
}, 500);
}
},
mounted() {
// set up timer on mounted
this.setIntervalTimer();
},
beforeDestroy() {
// do not forget clear the interval timer
clearInterval(this.timer);
}
};
</script>
答案 3 :(得分:0)
如果您使用的是vue.js,一个简单快捷的解决方案就是使用vue-infinite-scroll。
答案 4 :(得分:0)
基于@ ashishbansal的回答
for vue js 2 ...注意我主要使用ecma脚本6 ...如果你想使用旧的表示法你必须转换
现已安装
mounted() {
let app = this;
let distanceStartLoading = 300; //start loading stuff before reaching the very bottom right...
var endOfPage = function endOfPage() {
let bottomOfWindow = document.getElementsByTagName('body')[0].scrollTop + window.innerHeight >= document.documentElement.offsetHeight - distanceStartLoading;
if (bottomOfWindow) {
return true;
} else {
return false;
}
}
;(function () {
var throttle = function (type, name, obj) {
obj = obj || window;
var running = false;
var func = function () {
if (running) {
return;
}
running = true;
requestAnimationFrame(function () {
obj.dispatchEvent(new CustomEvent(name));
running = false;
});
};
obj.addEventListener(type, func);
};
/* init - you can init any event */
throttle("scroll", "optimizedScroll");
})();
// handle event
window.addEventListener("optimizedScroll", function () {
console.log("scrolling but not endofpage");
if (endOfPage()) {
console.log("hellow");
}
;
});
},