04 优化列表页面+下拉加载+处理无数据情况。
04 优化列表页面+下拉加载+处理无数据情况。
一 源代码(可以不用细看)
<template>
<view>
<!-- <block v-for="(item,index) in list" :key="index"> -->
<!-- 列表样式 -->
<!-- <common-list :item="item" :index="index" @follow="follow" @doSupport="doSupport"></common-list> -->
<!-- 全局分割线 -->
<!-- <divider></divider> -->
<!-- </block> -->
<!-- 顶部选项卡 -->
<scroll-view scroll-x="true" :scroll-into-view="scrollIndex" scroll-with-animation
class="scroll-row"
style="height: 100rpx;">
<view v-for="(item,index) in tabBars"
:key="index"
:id="'tab'+index"
class="scroll-row-item px-2 py-2 font-md"
:class="tabIndex === index? 'text-main font-lg font-weight-bold':''"
@click="changeTab(index)">
{{item.name}}
</view>
</scroll-view>
<!-- 定制选项卡对应的内容 -->
<!-- current 聚焦在当前子滑块实例的 index 默认会从0 1 2 3。。。依次排列 -->
<swiper :duration="10" :current="tabIndex" @change="onChangeTab"
:style="'height:'+scrollH+'px'">
<!-- 会默认分配索引 0 1 2 3 4 5 -->
<swiper-item v-for="(item,index) in newsList" :key="index">
{{item.name}}
<scroll-view scroll-y="true" :style="'height:'+scrollH+'px;'" @scrolltolower="loadmore(index)">
<!-- 列表 -->
<block v-for="(item2,index2) in item.list" :key="index2">
<!-- 列表样式 -->
<common-list :item="item2" :index="index2" @follow="follow" @doSupport="doSupport"></common-list>
<!-- 全局分割线 -->
<divider></divider>
</block>
<!-- 上拉加载 -->
<view class="flex align-center justify-center py-3">
<text class="font text-light-muted">
{{item.loadmore}}
</text>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
</template>
<script>
import commonList from '@/components/common/common-list.vue';
export default {
components: {
commonList
},
data() {
return {
scrollIndex:"",
tabIndex: 0,
tabBars: [{
name: '关注',
}, {
name: '推荐',
}, {
name: '体育',
}, {
name: '热点',
}, {
name: '财经',
}, {
name: '娱乐',
}, {
name: '军事',
}, {
name: '历史',
}, {
name: '本地',
}, {
name: '历史',
}, {
name: '历史',
}, {
name: '历史',
}, {
name: '历史',
}, {
name: '历史',
}, {
name: '历史',
}, {
name: '历史',
},],
newsList: []
}
},
onLoad() {
uni.getSystemInfo({
success:res=>{
// 可用窗口高度(屏幕高度-导航栏高度-底部栏高度。) - 选项卡高度
this.scrollH = res.windowHeight - uni.upx2px(101)
// console.log(this.scrollH)
}
})
// 根据选项生成列表
this.getData()
},
methods: {
// 上拉加载更多
loadmore(index){
// 拿到当前列表
let item = this.newsList[index]
// 修改当前加载状态
item.loadmore = '加载中。。。'
// 模拟数据请求
setTimeout(()=>{
// 加载数据
item.list = [...item.list,...item.list]
item.loadmore = '上拉加载更多'
},2000)
},
// 制作列表+上拉加载数据初始值
getData(){
var arr=[]
for (let i = 0; i < this.tabBars.length;i++ ){
let obj ={
loadmore:"上拉加载更多",
list:[{
username:"昵称",
userpic:"/static/default.jpg",
newstime:"2019-10-20 下午04:30",
isFollow:false,
title:"我是标题",
titlepic:"/static/demo/datapic/11.jpg",
support:{
type:"support", // 顶
support_count:1,
unsupport_count:2
},
comment_count:2,
share_num:2
},
{
username:"昵称",
userpic:"/static/default.jpg",
newstime:"2019-10-20 下午04:30",
isFollow:false,
title:"我是标题",
titlepic:"",
support:{
type:"unsupport", // 踩
support_count:1,
unsupport_count:2
},
comment_count:2,
share_num:2
},
{
username:"昵称",
userpic:"/static/default.jpg",
newstime:"2019-10-20 下午04:30",
isFollow:false,
title:"我是标题",
titlepic:"",
support:{
type:"", // 未操作
support_count:1,
unsupport_count:2
},
comment_count:2,
share_num:2
}]
}
arr.push(obj)
}
this.newsList = arr
},
follow(e){
this.list[e].isFollow = true;
uni.showToast({title:'关注成功'})
console.log('asdfa',e)
},
// 切换选项
changeTab(index){
if (this.tabIndex === index){
return;
}
this.tabIndex = index
// 视角滚动到指定元素
this.scrollIndex = 'tab'+index
},
// 监听选项内容滑动
onChangeTab(e){
this.changeTab(e.detail.current)
},
// 顶踩操作
doSupport(e){
// 拿到当前队对象
let item = this.list[e.index]
let msg = e.type === 'support' ? '顶' : '踩'
if (item.support.type === ''){
item.support[e.type+'_count']++
} else if (item.support.type === 'support' && e.type === 'unsupport'){
// 顶 -1
item.support.support_count--;
// 踩 +1
item.support.unsupport_count++;
} else if (item.support.type === 'unsupport' && e.type === 'support'){
// 踩 -1
item.support.unsupport_count --;
// 顶 +1
item.support.support_count ++;
}
item.support.type = e.type
uni.showToast({
title:msg+'成功'
})
}
}
}
</script>
<style>
</style>
二 优化列表页面没啥好说的(略)
三 下拉加载
思路:
1 首先在底部设置好最底部标签提示
2 在那个选项卡内容区定制loadmore:"上拉加载更多",
参数
3 scroll-view触底的时候会触发 @scrolltolower="loadmore(index)"
4 编写该loadmore(index)"事件逻辑
1 首先在底部设置好最底部标签提示
代码片段:
......
<scroll-view scroll-y="true" :style="'height:'+scrollH+'px;'" @scrolltolower="loadmore(index)">
<!-- 列表 -->
......
<!-- 上拉加载 -->
<view class="flex align-center justify-center py-3">
<text class="font text-light-muted">
{{item.loadmore}}
</text>
</view>
</scroll-view>
......
2 在那个选项卡内容区定制loadmore:"上拉加载更多",
参数
...
let obj ={
loadmore:"上拉加载更多",
list:[{
username:"昵称",
userpic:"/static/default.jpg",
newstime:"2019-10-20 下午04:30",
isFollow:false,
title:"我是标题",
titlepic:"/static/demo/datapic/11.jpg",
support:{
type:"support", // 顶
support_count:1,
unsupport_count:2
},
....
3 scroll-view触底的时候会触发 @scrolltolower="loadmore(index)"
...
<swiper :duration="10" :current="tabIndex" @change="onChangeTab"
:style="'height:'+scrollH+'px'">
<!-- 会默认分配索引 0 1 2 3 4 5 -->
<swiper-item v-for="(item,index) in newsList" :key="index">
{{item.name}}
<scroll-view scroll-y="true" :style="'height:'+scrollH+'px;'" @scrolltolower="loadmore(index)">
...
4 扩展运算符小点
// 加载数据
// ... 相当于取出来当前对象可以遍历出来的内容放到了当前对象里面。
// 这个可以粗糙的理解为把合并了两个一摸一样的列表,列表里面原来的内容*2了
item.list = [...item.list,...item.list]
item.loadmore = '上拉加载更多'
四 封装下拉加载组件
1 封装小组件
<template>
<view class="flex align-center justify-center py-3">
<text class="font text-light-muted">{{loadmore}}</text>
</view>
</template>
<script>
export default {
props: ['loadmore']
}
</script>
<style>
</style>
2 在页面组件面组册+使用+传参数
# 代码片段自己对应好位置
import loadMore from '@/components/common/load-more.vue'
export default {
components: {
commonList,
loadMore
},
<!-- 上拉加载 -->
<load-more :loadmore="item.loadmore"></load-more>
五 封装无数据组件
1 封装无数据小组件
<template>
<view class='flex flex-column align-center justify-center pt-5'>
<image src="/static/common/nothing.png"
style="width: 300rpx;height:300rpx;"></image>
<text class="font-md"> 什么都没有</text>
</view>
</template>
<script>
export default {
data() {
return {
}
}
}
</script>
<style>
</style>
2 全局引用 (main.js)
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
// 组册全局组件
import divider from './components/common/divider.vue';
import noThing from 'components/common/no-thing.vue'
Vue.component('divider',divider)
Vue.component('no-thing',noThing)
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
3 修改原来的页面组件
<scroll-view scroll-y="true" :style="'height:'+scrollH+'px;'" @scrolltolower="loadmore(index)">
<template v-if="item.list.length>0">
<!-- 列表 -->
<block v-for="(item2,index2) in item.list" :key="index2">
<!-- 列表样式 -->
<common-list :item="item2" :index="index2" @follow="follow" @doSupport="doSupport"></common-list>
<!-- 全局分割线 -->
<divider></divider>
</block>
<!-- 上拉加载 -->
<load-more :loadmore="item.loadmore"></load-more>
</template>
<template v-else>
<!-- 无数据渲染页面 -->
<no-thing></no-thing>
</template>
</scroll-view>