在微信項目中有應用過幾個上拉加載更多的組件,但總會出現一些兼容性方面的bug,需要各種補漏(注:組件都是基於iscroll實現的, iscroll原本就有些坑)。Vux也有提供Scroller組件實現上拉加載或下拉刷新,但官方已經不再維護該組件(未實際使用過,不知是否有坑)。所以這次我們采用更為簡單的方式來實現加載更多數據效果,廢話不多說,直接看效果圖。
實際效果圖
實現思路
組件模板
<template>
<div>
<div v-for="(item,idx) in tableData"
:key="idx"
class="box">
<slot :item="item"></slot>
</div>
<load-more v-if="loading"
tip="正在加載"></load-more>
<load-more v-else
:show-loading="false"
@click.prevent.native="load"
:tip="tipText"
background-color="#fbf9fe"></load-more>
</div>
</template>
結合后端分頁查詢接口
export default {
data () {
const _this = this
return {
tableData: [], // 列表數據
loading: false,
isLoadMore: true,
// 查詢參數
queryJson: (() => {
const { params } = _this
return params
})(),
pageIndex: 1, // 當前頁
total: 0 // 數據總條數
}
},
methods: {
load () {
if (!this.isLoadMore) {
return
}
this.fetch()
},
fetch () {
this.loading = true
let { url, pageSize, pageIndex, sortName, sordName, listField, totalField,
pageIndexField, pageSizeField, sortNameField, sordField } = this
let params = Object.assign({}, this.queryJson)
// 分頁參數
params = Object.assign(params, {
[pageIndexField]: pageIndex,
[pageSizeField]: pageSize
})
// 排序參數
params = Object.assign(params, {
[sortNameField]: sortName,
[sordField]: sordName
})
axios.get(url, { params }).then(response => {
this.total = response[totalField] // 總數
let result = response[listField] // 當次加載的數據
// 是否還可以加載更多 此種邏輯設計存在缺陷,如果在瀏覽列表的同時,又增加了新的記錄
this.isLoadMore = result.length === pageSize
this.pageIndex++
for (let item of result) {
this.tableData.push(item)
}
}).catch(error => {
console.error('獲取數據失敗 ', error)
}).finally(() => {
this.loading = false
})
}
}
}
變更loadmore組件內容
判斷isLoadMore(是否正在加載)的值,以及tableData(顯示數據列表內容) 的長度來控制底部loadmore組件顯示的內容
computed: {
tipText () {
// 暫無數據, 沒有更多數據, 輕按加載更多
if (!this.tableData || this.tableData.length === 0) {
return '暫無數據'
}
return this.isLoadMore ? '輕按加載更多' : '沒有更多數據'
}
},
監聽查詢參數的變化
watch: {
params: function (val) {
this.queryJson = val
this.pageIndex = 1
this.tableData = []
this.fetch()
}
},
具體應用
<template>
<div>
<group title='錢包明細'>
<vloadmore v-bind="table">
<template slot-scope="{ item }">
<cell-box>
<!-- 具體每一行的布局 -->
</cell-box>
</template>
</vloadmore>
</group>
</div>
</template>
<script>
import { Group, CellBox } from 'vux'
import { CsLoadMore } from '@/components'
export default {
data () {
return {
table: {
url: '/pms/wallet/getpagelist',
pageSize: 3
}
}
},
components: {
Group,
CellBox,
vloadmore: CsLoadMore
}
}
</script>
源碼
組件源碼請查看https://github.com/yinboxie/BlogExampleDemo/tree/master/Vux