赞
踩
使用 Vant van-pull-refresh van-list van-tab van-search遇到的问题总结
通过mixin
封装van-pull-refresh
+ van-list
, 实现下拉刷新 + 上拉加载,兼容切换tab changeTab
+ 搜索search
// mixin // 下拉刷新 + 上拉加载 export default { data () { return { list: [], page: 1, pageSize: 10, total: 0, // 下拉刷新 refreshing: false, // 上拉加载 loading: false, // 加载完毕 finished: false, // 其他操作状态需要保持页码不变 isKeepPage: false } }, mounted () { // 针对部分页面不需要在mounted阶段就初始化list, 判断如果在当前页面的options中有这个值且为真,则默认不加载list数据 // this.$options => https://www.cnblogs.com/luguankun/p/10856911.html let doNotInit = this.$options.doNotInit if (!doNotInit) { this.onLoad() } }, methods: { // 上拉加载 onLoad () { // 获取数据条件: finished 为假, 或total 为0, 或当前页面数据长度小于总数据长度 if (!this.finished || this.total === 0 || this.list.length < this.total) { // 显示加载的loading this.$toast.loading({ message: '加载中...', forbidClick: true }) // 调用引用的组件中的getList方法获取数据, 走对应的后台接口获取数据 return this.getList().then(res => { const resData = res.data.datalist // 将页码重置为后台传过来的page this.page = res.data.pagecond.page this.total = res.data.pagecond.count // 处理数据 if (this.page === 1) { this.list = resData } else { this.list = this.list.concat(resData) } // 没有返回数据, 或返回的数据为空, 结束加载 if (!resData || resData.length === 0) { this.finished = true return } return res }).catch(res => { // 接口请求报错, 结束请求, 给出报错信息 this.finished = true this.$toast(res.message) }).finally(() => { // 当前是否需要累加页码,如删除,修改等操作,可能需要操作后仍查看操作页数据,此时不累加。在引用组件的执行方法前设置 isKeepPage为true this.isKeepPage ? '' : this.page++ // 重置状态值 this.refreshing = false this.loading = false // 返回数据为空或最后一页不足分页条数或当前数据长度与数据总长度相等即没有数据了 this.finished = this.list.length >= this.total ? true : false // 清除loading this.$toast.clear() }) } else { // 不满足获取数据条件,重置状态值,且此时finished为true this.finished = true this.refreshing = false this.loading = false } }, // 下拉刷新 onRefresh () { // 只重置页码,不清空列表,直接覆盖数据 this.page = 1 // 重置状态, 此时finished为false, 在onLoad中再次判断状态 this.finished = false this.loading = true // 重新加载数据 this.onLoad() this.refreshing = false } } }
template
<!-- html --> <template> <div class="outer"> <van-pull-refresh v-model="refreshing" success-text="刷新成功" @refresh="onRefresh" > <van-list v-model="loading" :finished="finished" :immediate-check="false" :finished-text="list.length === 0 ? '' : '没有更多了'" error-text="请求失败,点击重新加载" @load="onLoad" > <van-tabs v-model="active" sticky animated color="#0061FF" title-active-color="#121C30" @change="changeTab" > <van-tab v-for="item in tabList" :key="item.index" :title="`${item.name}(${item.count})`" :name="item.label" > <van-search v-model="searchData" clearable placeholder="请输入金额" @clear="onClear" @search="onSearch" @cancel="onCancel" /> <div class="item" v-for="ele in list" :key="ele.index" @click="toDetail(ele)" > <!-- 需要循环的list内容 --> </div> <div v-if="list.length === 0" class="empty"> <img class="image" :src="" /> <p class="text mt-20">暂无数据</p> </div> </van-tab> </van-tabs> </van-list> </van-pull-refresh> </div> </template>
组件内的获取list
getList () { if (this.searchData !== '') { localStorage.setItem('searchData', this.searchData) } return new Promise((resolve, reject) => { const sendData = { page: this.page, pageSize: this.pageSize, // ... } getData(sendData).then(res => { if (res && res.code === '0') { // 处理下拉刷新 + 上拉加载外的其他操作 // 当前tab数量修改 let tabIndex = 0 this.tabList.forEach((item, index) => { if (this.active === item.label) { tabIndex = index } }) this.tabList[tabIndex].count = res.data.pagecond.count // 处理数据 resolve(res) } else { // 错误处理 this.$toast(res.message) } }).catch(err => { // 错误处理, 此时finished要为true reject(err) this.finished = true this.refreshing = false this.loading = false }) }) }
其他需要调用onRefresh
的方法
// 搜索和获取走的同一个接口, 直接调用onRefresh即可(list = 1后会重新覆盖数据)
onSearch () {
this.onRefresh()
},
// 获取tab对应的总数和数据是两个接口,再重新调用一下
onCancel () {
this.getCount()
this.onRefresh()
},
// 切换tab时, 同搜索, 调用onRefresh即可
changeTab () {
localStorage.setItem('active', this.active)
this.onRefresh()
}
css样式
.container {
min-height: 100vh;
overflow: auto;
background: @bgr;
}
不需要改变页码的情况
export default {
mixins: [listMixin],
doNotInit: true,
data: {},
methods: {},
...
}
有数据,但是不滚动
外层元素设置高度,并设置 overflow: auto
onLoad方法执行多次
immediate-check
属性 设置为 false
min-height: 100vh
(移动端) 或 特定高度refreshing
状态不对refresh后 直接加载了所有数据,一直在累加页码重新获取
finished
状态不对下拉刷新 直接在页面中间下拉就触发了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。