自定义指令 vue
-
全局自定义指令语法
Vue.directive('指令名字',{指令定义}) eg: index.vue improt { scroll } from './scroll'; // 在scroll.ts中 定义指令,再导入 Vue.directive('scroll',scroll) scroll.ts export default { // 钩子函数 }- 详细钩子函数介绍可以参考 Vue.js 自定义指令
- 在实现无限流加载,我们需要监听滚动条,因此,只需要绑定对应的el实例,也就是我们只需要用到 bind 和 unbind 钩子函数
-
官网对于 bind 和 unbind 的介绍
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置 unbind:只调用一次,指令与元素解绑时调用 -
钩子函数的参数有以下四个: el、binding、vnode、oldVnode,除了 el ,其他参数均只读
- el:指令所绑定的元素,可以用来直接操作 DOM
- binding:指令所绑定的对象,可以通过 binding.value 获取指令绑定的值,可以是一个函数,也可以是一个计算值,通过 binding.expression 获得指令的字符串表达式,其他参数请参考官方文档..
- vnode: Vue 编译生成的虚拟节点
- oldVnode:上一个虚拟节点,仅在
update和componentUpdated钩子中可用
实现原理
- 滚动条底部距离页面底部的距离小于某个定值(该定值绑定在 el 上,通过 el.getAttribute 获取该定值),便触发 binding 绑定的函数
directive.timer = setInterval(() => {
// 滑动到底部的距离:滑动的全部高度 - 容器的高度 - 滑动的顶部距离顶部的高度
const bottom = el.scrollHeight - el.clientHeight - el.scrollTop;
const disabled = el.getAttribute('scroll-disabled') === 'true';
const loadMoreFlag = loadMore && bottomDistance > bottom && !disabled && (el.clientHeight && el.scrollTop);
// console.log(`[direct.scrollpull] timer|${bottom}(bottom)|${bottomDistance}`
// + `(bottomDist)|${disabled}(disabled)|${loadMoreFlag}(loadMoreFlag)|${el.scrollTop}`
// + `(scrollTop) | ${el.scrollHeight}(scrollHeight) | ${el.clientHeight}(height)`);
loadMoreFlag && loadMore();
}, 500);
// 该div为页面根元素
<div v-scroll="loadMoreList" scroll-distance="600" :scroll-disabled="canScroll" v-on:scroll="scrollHandle" ref="loadmore">
</div>
.container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
overflow: hidden;
margin: 0;
padding: 0;
background-color: #f3f3f3;
overflow-y: scroll;
}