赞
踩
背景:
需要在el-tablel里实现滚动到底部加载更多数据
问题:使用element自带的无限滚动,但是实际用下来发现,指令只能作用于当前绑定的元素上,如下:
<ul class="infinite-list" v-infinite-scroll = "load" style="overflow:auto; height: 200px;">
<li v-for="(item, index) in tableData" :key="index">{{ item.name }}</li>
</ul>
对于不是真正的出现滚动条的标签,却无能为力
<el-table
border
height="400"
v-infinite-scroll="load"
:data="tableData"
>
<el-table-column prop="date" label="日期" width="180"></el-table-column>
<el-table-column prop="name" label="姓名" width="150"></el-table-column>
<el-table-column prop="address" label="地址" width="240"></el-table-column>
</el-table>
标签不是真正的容器,绑定了指令,无法生效
实现
第一步:判断滚到底部
const { scrollTop, scrollHeight, clientHeight } = targetEl
if(scrollHeight === scrollTop + clientHeight) {
console.log('到底部了!')
}
简洁版:
export default { name: 'load-more', bind(el, binding, vnode) { binding.handler = function(){ const {scrollTop, scrollHeight, clientHeight} = el if (scrollHeight === scrollTop + clientHeight) { binding.value && binding.value() } } el.addEventListener('scroll', binding.handler) }, unbind(el, binding) { el.removeEventListener('scroll', binding.handler) el = null } }
把写好的指令在组件内注册后,即可生效。
我们的指令能够支持:
完整代码:
<template> <div> <el-table border height="400" :data="visibleData" :row-key="getRowKeys" v-load-more.expand="{func: loadmore, target: '.el-table__body-wrapper', delay: 300}" :load-more-disabled="disabledLoad" @selection-change="handleSelectionChange" > <el-table-column type="selection" :reserve-selection="true" width="55"> </el-table-column> <el-table-column prop="date" label="日期" width="180"></el-table-column> <div slot="append" style="text-align: center;">滚动到底部加载更多</div> </el-table> </div> </template> <script> 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) } } export default { directives: { 'load-more': { bind (el, binding, vnode) { const { expand } = binding.modifiers // 使用更丰富的功能,支持父组件的指令作用在指定的子组件上 if (expand) { /** * target 目标DOM节点的类名 * distance 减少触发加载的距离阈值,单位为px * func 触发的方法 * delay 防抖时延,单位为ms * load-more-disabled 是否禁用无限加载 */ let { target, distance = 0, func, delay = 200 } = binding.value if (typeof target !== 'string') return let targetEl = el.querySelector(target) if (!targetEl) { console.log('找不到容器') return } binding.handler = debounce(function () { const { scrollTop, scrollHeight, clientHeight } = targetEl let disabled = el.getAttribute('load-more-disabled') disabled = vnode[disabled] || disabled if (scrollHeight <= scrollTop + clientHeight + distance) { if (disabled) return func && func() } }, delay) targetEl.addEventListener('scroll', binding.handler) } else { binding.handler = helper.debounce(function () { const { scrollTop, scrollHeight, clientHeight } = el if (scrollHeight === scrollTop + clientHeight) { binding.value && binding.value() } }, 200) el.addEventListener('scroll', binding.handler) } }, unbind (el, binding) { 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 } } } }, data() { return { visibleCount: 10, tableData: [ {id: '234', date: '2016-06-01'}, {id: '34', date: '2016-06-01'}, {id: '24', date: '2016-06-01'}, {id: '23242', date: '2016-06-01'}, {id: '23243', date: '2016-06-01'}, {id: '23244', date: '2016-06-01'}, {id: '23245', date: '2016-06-01'}, {id: '23246', date: '2016-06-01'}, {id: '23247', date: '2016-06-01'}, {id: '23248', date: '2016-06-01'} ], multipleSelection: [] } }, created() { let count = 1 while(count >= 0) { count-- this.tableData.push( { id: '1213', date: '2016-05-02' }, { id: '11123', date: '2016-05-02' }, { id: '123023', date: '2016-05-02' }, { id: '1253', date: '2016-05-02' }, { id: '1243', date: '2016-05-02' }, { id: '1263', date: '2016-05-02' }, { id: '1273', date: '2016-05-02' }, { id: '1283', date: '2016-05-02' }, { id: '1293', date: '2016-05-02' }, { id: '1203', date: '2016-05-02' }, { id: '1323', date: '2016-05-02' }, { id: '1423', date: '2016-05-02' }, { id: '1523', date: '2016-05-02' }, { id: '1623', date: '2016-05-02' }, { id: '1723', date: '2016-05-02' }, { id: '1823', date: '2016-05-02' }, { id: '1923', date: '2016-05-02' }, { id: '1023', date: '2016-05-02' }, { id: '12323', date: '2016-05-02' }, { id: '134323', date: '2016-05-02' } ) } }, computed: { disabledLoad() { return false }, visibleData() { return this.tableData.slice(0, Math.min(this.tableData.length, this.visibleCount)) } }, methods: { loadmore() { console.log('滚动到底部了'); this.visibleCount += 10; }, handleSelectionChange(val) { this.multipleSelection = val; console.log(this.multipleSelection) const ids = this.multipleSelection.map(item => { return item.id }) console.log(ids) }, getRowKeys(row) { return row.id } } } </script>
注:
el-table
里的:row-key="getRowKeys"
和@selection-change="handleSelectionChange"
配合el-table-column
里的:reserve-selection="true"
实现了无限加载的同时记住已选内容
参考文章:
element-ui表格 实现滚动到底部加载更多
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。