说明
自用
一、自定义指令实现
参考:
vue element-ui table表格滚动加载
-
template
我~是有底线的 (~ ̄▽ ̄)~
-
script
export default {
name: 'WbTable',
// 自定义指令
// vue 官方文档:https://cn.vuejs.org/v2/guide/custom-directive.html
directives: {
loadmore: {
bind (el, binding) {
const selectWrap = el.querySelector('.el-table__body-wrapper')
selectWrap.addEventListener('scroll', function () {
let sign = 100
const scrollDistance = this.scrollHeight - this.scrollTop - this.clientHeight
if (scrollDistance <= sign) {
binding.value()
}
})
}
}
},
props: {
// 服务端列表数据接口名称
url: {
type: String,
required: true
},
// 服务端列表数据接口请求参数
params: {
type: Object,
required: true
}
},
data () {
return {
tableData: [],
loading: false,
total: 0
}
},
created () {
this.limit = this.params.limit ? this.params.limit : 8
this.offset = this.params.offset ? this.params.offset : 0
// 根据单元格最小高度计算表格高度
this.height = this.limit * 45
this.append(this.params)
},
methods: {
append (params) {
this.loading = true
this.$http[this.url]({
...params,
offset: this.offset,
limit: this.limit
})
.then(result => {
this.tableData = [
...this.tableData,
...result.data.rows
]
console.log(this.tableData)
this.total = result.data.total || 0
})
.finally(() => {
this.loading = false
})
},
reload () {
// 刷新重置 offset 和表格
this.params.offset = 0
this.tableData = []
// api动态加载完 开始重新请求数据
this.$nextTick(() => {
this.init(this.params)
})
},
// 滚动事件
loadMore () {
const newOffset = this.offset + this.limit
if (newOffset < this.total && !this.loading) {
this.offset = newOffset
this.append(this.params)
}
}
}
}
-
3.效果
二、与el-infinite-scroll
结合
有大佬已经实现了,查看:
element-ui 的 el-table 上使用无限滚动加载(与自带的 infinite-scroll 结合):https://blog.csdn.net/baidu_27769027/article/details/101924676
GitHub代码:https://github.com/yujinpan/el-table-infinite-scroll/blob/master/src/directives/table-infinite-scroll.js
三、 使用vue-infinite-loading
实现滚动加载
参考:
官方文档(中文):https://peachscript.github.io/vue-infinite-loading/zh/
vue elmentui table 滚动加载:https://www.jianshu.com/p/48df3fd85dd6
1. 安装
注意:vue-infinite-loading2.0只能在Vue.js2.0中使用。如果你想在Vue.js1.0中使用,请安装vue-infinite-loading1.3版本
npm install vue-infinite-loading --save
2.引入
import InfiniteLoading from 'vue-infinite-loading'
export default {
name: 'WbTable',
components: {InfiniteLoading}
}
3.完整使用
template
我~是有底线的 (~ ̄▽ ̄)~
暂无结果 Ծ‸Ծ
出错了 (╯‵□′)╯︵┻━┻
script
import InfiniteLoading from 'vue-infinite-loading'
export default {
name: 'WbTable',
components: {InfiniteLoading},
props: {
// 服务端列表数据接口名称
url: {
type: String,
required: true
},
// 服务端列表数据接口请求参数
params: {
type: Object,
required: true
}
},
data () {
return {
tableData: [],
loading: false,
total: 0,
isOver: false,
infiniteId: new Date()
}
},
created () {
this.limit = this.params.limit ? this.params.limit : 8
this.offset = this.params.offset ? this.params.offset : 0
// 根据单元格最小高度计算表格高度
this.height = this.limit * 45
},
methods: {
// 滚动事件
async loadMore ($state) {
this.loading = true
if (!this.isOver) {
await this.$http[this.url]({
...this.params,
offset: this.offset,
limit: this.limit
})
.then((result) => {
this.tableData = [
...this.tableData,
...result.data.rows
]
this.total = result.data.total || 0
if (this.total <= this.tableData.length) {
this.isOver = true
$state.complete() // 全部加载完成
} else {
$state.loaded() // 单个数据加载完毕
this.offset = this.offset + this.limit // 设置下一页
}
console.log(this.tableData, this.total)
})
.finally(() => {
this.loading = false
})
}
},
reset () {
this.offset = 0
this.tableData = []
this.infiniteId += 1
}
}
}
四、手动加载下一页
运用el-table
的插槽append
设置一个加载按钮,手动触发页面加载
template
出错了 (╯‵□′)╯︵┻━┻
暂无数据 Ծ‸Ծ
我~是有底线的 (~ ̄▽ ̄)~
script
export default {
name: 'WbTable',
props: {
// 服务端列表数据接口名称
url: {
type: String,
required: true
},
// 服务端列表数据接口请求参数
params: {
type: Object,
required: true
},
height: {
type: [String, Number],
default () {
return 0
}
}
},
data () {
return {
tableData: [],
loading: false,
total: 0,
isOver: false,
isError: false,
noMore: false
}
},
created () {
this.limit = this.params.limit ? this.params.limit : 8
this.offset = this.params.offset ? this.params.offset : 0
// 取设置的高度,否则按最小高度计算
this.tableHeight = this.height ? this.height : this.limit * 45 + 80
this.append(this.params)
},
methods: {
// 列表新增
async append (params) {
this.loading = true
this.$http[this.url]({
...params,
offset: this.offset,
limit: this.limit
})
.then(result => {
if (!result.data) {
this.noMore = true
return
}
this.tableData = [
...this.tableData,
...result.data.rows
]
this.total = result.data.total || 0
console.log(this.tableData, this.total)
// 判断是否需要加载下一页
if (this.tableData.length >= this.total) {
this.isOver = true
}
})
// eslint-disable-next-line handle-callback-err
.catch(error => {
this.isError = true
})
.finally(() => {
this.loading = false
})
},
reset () {
debugger
this.offset = 0
this.tableData = []
this.total = 0
this.isOver = false
this.isError = false
this.noMore = false
// api动态加载完 开始重新请求数据
this.$nextTick(() => {
this.append(this.params)
})
},
nextPage (event) {
if (!this.isOver) {
this.offset = this.offset + this.limit
this.$nextTick(() => {
this.append(this.params)
})
}
}
}
}
style