美文网首页
Vue自定义指令-虚加载

Vue自定义指令-虚加载

作者: 欢西西西 | 来源:发表于2022-08-26 11:37 被阅读0次

指令文件:

// 有可能list的el和绑定scroll的el并不是一个,把paddingTop和paddingBottom传出去自己设置到list上
const toUpdateData = function ({ maxDrawCount, itemHeight, updateRealDrawList: fnUpt }, el) {
    const allData = el.__allData__ || [];
    let dataCount = allData.length;
    if (dataCount <= maxDrawCount) {
        el.dataset.startindex = 0;
        return fnUpt({
            data: allData,
            paddingTop: 0,
            paddingBottom: 0
        });
    }
    const start = el.dataset.startindex * 1;
    let drawEndIndex = Math.min(start + maxDrawCount, dataCount);
    let paddingTop = start * itemHeight + "px";
    let paddingBottom = (dataCount - drawEndIndex) * itemHeight + "px";
    let realDrawList = allData.slice(start, drawEndIndex);
    fnUpt({
        data: realDrawList,
        paddingTop,
        paddingBottom
    });
};


/**
 * 指令的binding对象接收:
 * {Array} data 列表的总数据
 * {Number} maxDrawCount 实际在页面上最多渲染多少条数据
 * {Number} itemHeight 每条数据的高度
 * {Function} updateRealDrawList 自动计算出要渲染的数据时会将(data, paddingTop, paddingBottom)作为入参调用此更新方法
 * 在使用此指令的页面将data更新为要渲染的列表,将paddingTop, paddingBottom绑定在列表上
 */
export default {
    bind: function (el, binding) {
        // 当滚动时updateRealDrawList
        el.addEventListener('scroll', (function () {
            let scrollTimer = null;
            return function () {
                if (scrollTimer) {
                    return;
                }
                scrollTimer = setTimeout(() => {
                    let { itemHeight } = binding.value;
                    let v = parseInt(el.scrollTop / itemHeight),
                        startIndex = v > 4 ? v - 4 : 0; // 在上方不可见范围内再渲染4个
                    el.dataset.startindex = startIndex;
                    toUpdateData(binding.value, el);
                    clearTimeout(scrollTimer);
                    scrollTimer = null;
                }, 250);
            };
        })());
    },
    update: function (el, binding) { // 当总列表改变时updateRealDrawList
        let { data } = binding.value;
        if (data === el.__allData__) {
            return;
        }

        // 因为各个页面都有可能要用这个指令,数据不能存在全局变量,会造成各页面都公用这份数据。所以现在挂在el上
        el.__allData__ = data;
        toUpdateData(binding.value, el);
    },
};

使用指令

<div v-virtualscroll="{
        data: allData,
        maxDrawCount: 20,
        itemHeight: 100,
        updateRealDrawList: onUptDrawList,
      }">
<!-- 渲染drawList列表,并将paddingTop ,paddingBottom 设置到style  -->
</div>
import VirtualScroll from "@/utils/VirtualScroll.js";
export default {
  directives: {
    "virtualscroll": VirtualScroll,
  },
  methods: {
     onUptDrawList({ data, paddingTop, paddingBottom }) {
        this.drawList = data;
        this.paddingTop = paddingTop;
        this.paddingBottom = paddingBottom;
    },
  }
}

自定义指令一个重要的问题:如何传值

1、指令的这些钩子函数里面如何拿到组件中的数据?

  • 一是绑定在dom上,因为钩子里都能拿到el再从el上读取,一般用于静态参数
  • 二是在绑定指令的时候传入,例:v-mycopy="billSn",在钩子里使用value参数来获取传入的值,用于动态参数。

2、在哪里监控入参的更新?

image.png
  • 注意update钩子,所在组件的VNode更新,就会调update。这个VNode更新,可能原因是入参绑定的数据更新了,也可能是其他数据更新导致的,所以指令的入参值是否发生了更新需要自己判断。举个例子:
<template>
  <div>
    <div v-mycopy="userName">复制</div>
    <div>{{ billSn }}</div>
  </div>
</template>

当billSn改变时,依然会调mycopy指令的update,但userName并没有变

  • 假如template中只有一个<div v-mycopy="userInfo"></div>,传给指令的是个引用型的数据,那么只有userInfo这个引用发生改变的时候,才会去调update,只更改userInfo中的属性值是不会触发的;

3、指令的钩子中能改变组件中的数据吗?

image.png

相关文章

  • Vue自定义指令-虚加载

    指令文件: 使用指令 自定义指令一个重要的问题:如何传值 1、指令的这些钩子函数里面如何拿到组件中的数据? 一是绑...

  • vue 2.0 自定义指令

    前言 自定义指令的简要介绍,以及图片懒加载的应用。 语法介绍 注册全局指令Vue.directive('lazy'...

  • season2-全局API

    第1节:Vue.directive 自定义指令 Vue.directive自定义指令 自定义的指令:changec...

  • vue-element(四) el-table滚动加载

    说明 自用 一、自定义指令实现 参考: vue element-ui table表格滚动加载 template s...

  • Vue div节点滚动事件-加载更多

    使用Vue.directive注册全局指令 绑定事件 对于Vue自定义指令不明白的同学请移步: Vue自定义指令 ...

  • VUE-2:自定义指令、事件

    directive自定义指令 我们还可以通过`Vue`提供的directive方法来自定义指令 注册指令 `vue...

  • vue入门6---vue基本指令、自定义指令、插件

    一、vue常用指令概览 二、vue自定义指令 注册全局指令Vue.directive('my-directive'...

  • 实现一个简单的 vue 无限加载指令

    vue 中的自定义指令是对底层 dom 进行操作,下面以实现滚动到底部加载数据,实现无限加载来介绍如何自定义一个简...

  • vue自定义指令初探

    vue自定义指令初探 一、什么是自定义指令 自定义指令是用来操作DOM的。尽管Vue推崇数据驱动视图的理念,但并非...

  • vue 有自定义指令

    vue 的自定义指令,分为全局自定义指令和局部自定义指令,局部自定义指令等价于局部组件。 自定义指令可以对DOM进...

网友评论

      本文标题:Vue自定义指令-虚加载

      本文链接:https://www.haomeiwen.com/subject/qwczgrtx.html