Vue3自定义指令 +ant design vue table组件实现滚动加载

 以下为前台模拟滚动加载数据,实际开发应用中,可在 tableLoad 函数中调用接口向后台请求下一页数据

<template>
    <a-table
        :columns="staffColumns"
        :dataSource="dataSource"
        :pagination="false"
        :rowKey="record => record.staffId"
        ref="tableRef"
        :scroll="{
          x: 400,
          y: 545
        }"
        v-loadMore.expand="{ func: tableLoad, target: '.ant-table-body', delay: 300, distance: 10 }"
      >
      </a-table>
</template>
<script>
import { reactive,toRefs,ref } from 'vue'
import { staffColumns } from '../../columns'
    export default {
         setup() {
            const dataSource = ref([]) //列表数据
            const tableRef = ref(null)
            const state = reactive({
                currentPage:1, //当前页码
                total:[], //列表总数据
                start: 0, //数据截取开始位置
            })
              
            //加载更多
            const tableLoad = () => {
              
               //超过最大页数不继续执行
              if (state.currentPage>= Math.ceil(state.total.length / 10)) {
                tableRef.value.$el.setAttribute('load-more-disabled', 'true')
                return
              }
              state.currentPage += 1
              state.start += 10
              dataSource.value = [...dataSource.value, ...state.total.slice(state.start, state.start + 10)]
             }
            return{
                tableLoad,
                dataSource,
                tableRef,
                 ...toRefs(state),  
            }
        }
    }
      </script>

使用vue3 自定义指令 实现滚动事件监听

注册自定义指令

// src/utils/loadMore.js


import { Directive, App } from 'vue'

const debounce = function(func, delay) {
  let timer = null
  return function() {
    if (timer) clearTimeout(timer)
    timer = null
    let self = this
    let args = arguments
    timer = setTimeout(() => {
      func.apply(self, args)
    }, delay)
  }
}

const loadMore = {
  mounted(el, binding, vnode) {
    
    //为dom节点设置 load-more-disabled 属性
    el.setAttribute('load-more-disabled', 'false')
    const { expand } = binding.modifiers
    // 使用更丰富的功能,支持父组件的指令作用在指定的子组件上
    if (expand) {
      /**
       * target 目标DOM节点的类名
       * distance 减少触发加载的距离阈值,单位为px
       * func 触发的方法\-0
       * delay 防抖时延,单位为ms
       * load-more-disabled 是否禁用无限加载
       */
      let { target, distance = 0, func, delay = 200 } = binding.value
      if (typeof target !== 'string') return
      let targetEl = el.querySelector(target)
      console.log('targetEl', targetEl)
      if (!targetEl) {
        console.log('找不到容器')
        return
      }
      binding.handler = function() {
        const { scrollTop, scrollHeight, clientHeight } = targetEl

        let disabled = el.getAttribute('load-more-disabled')
        // disabled = vnode[disabled] || disabled
        if (scrollHeight <= scrollTop + clientHeight + distance) {
          if (disabled == 'true') return
          func && func()
        }
      }
      targetEl.addEventListener('scroll', binding.handler)
    } else {
      binding.handler = debounce(function() {
        const { scrollTop, scrollHeight, clientHeight } = el
        if (scrollHeight === scrollTop + clientHeight) {
          binding.value && binding.value()
        }
      }, 200)
      el.addEventListener('scroll', binding.handler)
    }
  },
  unmounted(el, binding) {
    console.log('卸载了 ')
    let { arg } = binding
    // 使用更丰富的功能,支持父组件的指令作用在指定的子组件上
    if (arg === 'expand') {
      /**
       * target 目标DOM节点的类名
       * offset 触发加载的距离阈值,单位为px
       * method 触发的方法
       * delay 防抖时延,单位为ms
       */
      const { target } = binding.value
      if (typeof target !== 'string') return
      let targetEl = el.querySelector(target)
      targetEl && targetEl.removeEventListener('scroll', binding.handler)
      targetEl = null
    } else {
      el.removeEventListener('scroll', binding.handler)
      el = null
    }
  }
}

export function setupLoadMoreDirective(app) {
  app.directive('loadMore', loadMore)
}

export default loadMore
// main.js

import { createApp } from 'vue'
import App from './App.vue' // 入口文件
import { setupLoadMoreDirective } from '@/utils/loadMore.js' //表格滚动加载


const app = createApp(App)
setupLoadMoreDirective(app)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值