在官网中,vue-infinite-scroll是这样使用的。
<template>
<div class="infinite-list-wrapper" style="overflow:auto">
<ul
class="list"
v-infinite-scroll="load"
infinite-scroll-disabled="disabled">
<li v-for="i in count" class="list-item">{{ i }}</li>
</ul>
<p v-if="loading">加载中...</p>
<p v-if="noMore">没有更多了</p>
</div>
</template>
在某些需求下,我们需要给v-infinite-scroll的函数加上参数。首先更具排除法,肯定不是v-infinite-scroll=“load(params)”,这样会使列表不根据距离而无限加载,这也是导致我们使用无限加载常常看到报错的原因之一。
v-infinite-scroll是一个自定义指令。而自定义指令的参数是这样表示的 v-mydirective:[argument]=“value”,你可以这样获取参数值。
Vue.directive('demo', {
bind: function (el, binding, vnode) {
consoloe.log("传入的参数", binding.arg);
}
})
我们试一下把 v-infinite-scroll="load"改为 v-infinite-scroll[params]="load"试试,但是还是不行,这时候我们就需要看一下源码了
export default {
name: 'InfiniteScroll',
inserted(el, binding, vnode) {
const cb = binding.value;
const vm = vnode.context;
// only include vertical scroll
const container = getScrollContainer(el, true);
const { delay, immediate } = getScrollOptions(el, vm);
const onScroll = throttle(delay, handleScroll.bind(el, cb));
el[scope] = { el, vm, container, onScroll };
if (container) {
container.addEventListener('scroll', onScroll);
if (immediate) {
const observer = el[scope].observer = new MutationObserver(onScroll);
observer.observe(container, { childList: true, subtree: true });
onScroll();
}
}
},
unbind(el) {
const { container, onScroll } = el[scope];
if (container) {
container.removeEventListener('scroll', onScroll);
}
}
};
我们看一下的确没有binding.arg,那我们就需要改造一下这个自定义指令了。
const newInfiniteScroll = {
name: 'testInfiniteScroll',
inserted(el, binding, vnode) {
const cb = binding.value;
const vm = vnode.context;
// only include vertical scroll
const container = getScrollContainer(el, true);
const {
delay,
immediate
} = getScrollOptions(el, vm);
const onScroll = throttle(delay, handleScroll.bind(el, cb, binding.arg));
el[scope] = {
el,
vm,
container,
onScroll
};
if (container) {
container.addEventListener('scroll', onScroll);
if (immediate) {
const observer = el[scope].observer = new MutationObserver(onScroll);
observer.observe(container, {
childList: true,
subtree: true
});
onScroll();
}
}
},
unbind(el) {
const {
container,
onScroll
} = el[scope];
if (container) {
container.removeEventListener('scroll', onScroll);
}
}
};
然后handleScroll 也改一下。
const handleScroll = function (cb, arg) {
const {
el,
vm,
container,
observer
} = this[scope];
const {
distance,
disabled
} = getScrollOptions(el, vm);
if (disabled) return;
let shouldTrigger = false;
if (container === el) {
// be aware of difference between clientHeight & offsetHeight & window.getComputedStyle().height
const scrollBottom = container.scrollTop + getClientHeight(container);
shouldTrigger = container.scrollHeight - scrollBottom <= distance;
} else {
const heightBelowTop = getOffsetHeight(el) + getElementTop(el) - getElementTop(container);
const offsetHeight = getOffsetHeight(container);
const borderBottom = Number.parseFloat(getStyleComputedProperty(container, 'borderBottomWidth'));
shouldTrigger = heightBelowTop - offsetHeight + borderBottom <= distance;
}
if (shouldTrigger && isFunction(cb)) {
cb.call(vm, arg);
} else if (observer) {
observer.disconnect();
this[scope].observer = null;
}
};
<ul
class="list"
v-test-infinite-scroll[params]="load"
infinite-scroll-disabled="disabled">
<li v-for="i in count" class="list-item">{{ i }}</li>
</ul>
load(params) {
//params 为传入的参数
}