vue之element-ui表格加载更多自定义指令

2020-04-07  本文已影响0人  f3d003f8d312
/*
    防抖 延时执行
    @param fn function
    @param wait number
    @return function
*/
const debounce = (fn, wait) => {
    var timeout = null
    return () => {
        if (timeout !== null) clearTimeout(timeout)
        timeout = setTimeout(fn, wait)
    }
}
Vue.directive('elTableScrollLoad', {
    inserted(el, binding) {
        let loadEnd = binding.value.loadEnd
        el.timeout = null
        el.timer = null
        // 防止首次加载不够填满容器
        if (!loadEnd) {
            const selectWrap = el.querySelector('.el-table__body-wrapper')
            el.timeout = setTimeout(() => {
                let elTableWrap = parseFloat(el.style.maxHeight || el.style.height)
                if (selectWrap.scrollHeight <= elTableWrap && selectWrap.scrollHeight !== 0 && !loadEnd) {
                    el.timer = setInterval(() => {
                        binding.value.load()
                        if (selectWrap.scrollHeight > elTableWrap) {
                            clearInterval(el.timer)
                            clearTimeout(el.timeout)
                        }
                    }, 1500)
                }
            }, 500)
        }
    },
    async bind(el, binding) {
        let loadEnd = binding.value.loadEnd
        let loadingText = binding.loadingText || '加载中...'
        let loadendText = binding.loadendText || '没有更多了'
        const selectWrap = el.querySelector('.el-table__body-wrapper')
        let remove = () => {
            let ele = el.querySelector('.el-table__body-wrapper').querySelector('.tableloadmoretext')
            if (ele) {
                selectWrap.removeChild(ele)
            }
        }
        if (!loadEnd) {
            let fun = () => {
                let sign = 0
                const scrollDistance = selectWrap.scrollHeight - Math.ceil(selectWrap.scrollTop) - Math.ceil(selectWrap.clientHeight)
                if (scrollDistance <= sign) {
                    binding.value.load()
                }
            }

            let vueScrollEvent = debounce(fun, 500)
            el._vueScrollEvent = vueScrollEvent
            selectWrap.addEventListener('scroll', vueScrollEvent)
            remove()
            let h = document.createElement('div')
            h.innerHTML = `<p>${loadingText}</p>`
            h.style = 'text-align:center;'
            h.className = 'tableloadmoretext'
            h.dataname = 'loading'
            selectWrap.appendChild(h)
        }
        if (loadEnd) {
            remove()
            let h = document.createElement('div')
            h.innerHTML = `<p>${loadendText}</p>`
            h.style = 'text-align:center;'
            h.className = 'tableloadmoretext'
            h.dataname = 'loaded'
            selectWrap.appendChild(h)
        }
    },
    update(el, binding) {
        if (binding.value.loadEnd) {
            clearInterval(el.timer)
            clearTimeout(el.timeout)
        }
        // loading loaded none
        let loadingText = binding.loadingText || '加载中...'
        let loadendText = binding.loadendText || '没有更多了'
        if (binding.value.loadEnd !== binding.oldValue.loadEnd) {
            const selectWrap = el.querySelector('.el-table__body-wrapper')
            let remove = () => {
                let ele = el.querySelector('.el-table__body-wrapper').querySelector('.tableloadmoretext')
                if (ele) {
                    selectWrap.removeChild(ele)
                }
            }
            if (binding.value.loadEnd) {
                remove()
                let h = document.createElement('div')
                h.innerHTML = `<p>${loadendText}</p>`
                h.style = 'text-align:center;'
                h.className = 'tableloadmoretext'
                h.dataname = 'loaded'
                selectWrap.appendChild(h)
            }
            if (!binding.value.loadEnd) {
                remove()
                let h = document.createElement('div')
                h.innerHTML = `<p>${loadingText}</p>`
                h.style = 'text-align:center;'
                h.className = 'tableloadmoretext'
                h.dataname = 'loading'
                selectWrap.appendChild(h)
            }
        }
    },
    unbind(el) {
        clearInterval(el.timer)
        clearTimeout(el.timeout)
        const selectWrap = el.querySelector('.el-table__body-wrapper')
        selectWrap.removeEventListener('scroll', el._vueScrollEvent)
    },
})

使用指令

<!-- 使用table需设置max-height或height -->
<el-table
  v-elTableScrollLoad="{ 
    load: load, 
    loadEnd: tableloadStatus,
    loadingText:'loading...'
    loadendText:'no more'
  }"
  :max-height="scrollHeight"
  :data="tableData"
>
<template slot="empty">
  <div></div>
</template>
</el-table>

指令配置

 v-elTableScrollLoad="{ 
  load: load, // 加载数据回调函数 必填
  loadEnd: tableloadStatus, // 是否加载完成标志 Boolean 必填
  loadingText:'loading...' //  加载中文字  string 非必填
  loadendText:'no more'  //   加载完成文字  string 非必填
}"
上一篇下一篇

猜你喜欢

热点阅读