这一章学习了触底加载更多阻止无效的网络请求、分类列表存入Storage在预览页面读取缓存展示、通过swiper的事件实现真正的壁纸预览及切换
触底加载更多阻止无效的网络请求、load-more样式的展现
前面已经学习了当列表触底后,会继续加载,当到最后一层后,给出一个已经没有了的提示。这一章把这个功能继续完成下。在老师的视频中,给出了使用插件,z-paging插件,我这边下载下来,试用了下,发现完全无头脑,不会使用,只能是回归到使用onReachBottom中,这里有许多细节,我这边现在一步一步说。
当列表滑动到最后一层后,要给个提示,并且不能再让获取数据了,因为已经是最后一层了,在获取数据只会消耗网络,不会有新的数据了,这里设置一个标记符,const noData=ref(false),默认是false,当获取到最后一层后,没有数据的时候,那接口参数的默认值数量就会大于接口返回的数量,这就给noData变成true,让不在加载数据了,这就达到了阻止无效的网络请求了。
刚进入页面后要给个正在加载的提示,这里使用组件uni-load-more,给设定是lading,就达到这个效果了,在实验过程中,发现当进入的时候,会出现两个或者是数据已经出来了但是提示框还在,这里就要使用定义的标记符和数据在页面进行判断了,
<!-- 这是顶部的刷新提示 -->
<view class="ladingLayout" v-if="!classList.length && !noData"><uni-load-more status="loading"></uni-load-more>
</view>
<!-- 这是底部的加载或者最后一页的提示 -->
<view class="ladingLayout" v-if="noData || classList.length"><uni-load-more :status="noData ? 'noMore' : 'loading'"></uni-load-more>
</view>
上面就是刷新的时候,要进行判断,这里记录下两个判断的依据:
第一个v-if:这里是当刚进入页面获取数据,那数据集合是空的,noData也是false,这就提示正在加载,这里使用的是&&的关系,只有两个都满足,才会显示uni-load-more
第二个v-if:当还没有到最后一层的时候,不论是数据源还是noData,都已经变成true或者是有值,只有两个中的任何一个满足条件,就显示uni-load-more;这里给uni-load-more的status设置了两种情况,当noData是true的时候,uni-load-more就显示的是没有数据了,反之显示正在加载
下面是设置的js
const noData = ref(false)const getClassList = async () => {let res = await apiClassList(queryParams);classList.value = [...classList.value, ...res.data];if (queryParams.pageSize > res.data.length) {noData.value = true}uni.setStorageSync("storageClassList", classList.value);console.log(res);}// 触底加载更多onReachBottom(() => {if (noData.value) return;queryParams.pageNum++;getClassList();})
这里提出一个概念,骨架屏,是什么?查了网络才知道,其实就是设置的加载占位图,就是前面做的这些,只是叫法不同而已。
在小程序中,出现一种情况,就是在虚拟机上,有个虚拟的home键,会把正在加载的提示给遮挡住,这里就需要用到前面学习的,设定一个安全高度,在html最下面,设置一个空的组件,设置安全高度,<view class="safe-area-inset-bottom"></view>
;这里使用的class名称,就是在公共区域设置的安全高度,想着可能使用安全高度的地方会很多,那就把这个区域高度放在公共css中,
.safe-area-inset-bottom{height:env(safe-area-inset-bottom);
}
env(safe-area-inset-bottom) 这就是我们设置的安全区域高度
数据存入Storage在预览页面读取缓存展示
在项目中,是根据图片的类型,获取该类型下的图片,获取的数据会很多,然后点击图片进行预览的时候,总不能每一次都获取一次数据吧,这样太消耗性能了,因此,在获取到列表后,将列表数据放在缓存中,预览的时候,只用从缓存中拿到数据源,在展示就可以了。
数据存储到缓存
数据是一个对象,那么存储到缓存的时候,就要使用:
uni.setStorageSync("storageClassList", classList.value);
,storageClassList,这是名称,方便在使用的地方根据名称取值的,后面的是数据源。
获取缓存的数据
const storageClassList = uni.getStorageSync("storageClassList") || []; //获取缓存中的数据源
这就是获取缓存数据,后面加的||[],这是预防当缓存中没有数据,给一个默认的值,
现在已经把数据拿到了,那就只用把数据放在页面上进行渲染就可以了,
通过swiper的事件实现真正的壁纸预览及切换
数据在页面上已经显示出来了,但是在滑动的时候,并没有更改前面的数量,这里的数据是当前图片的下标/总数,那要怎么使用这个呢?这里可以让从列表上点击的时候,就把当前图片的id传给预览页面,这样就能根据findIndex将下标得到,通过swiper的属性current属性,可以让显示当前下标下的图片,这个下标加一也是提示的位置,
这里把当前这个页面的代码全部给出,大家可以学习下,
<swiper circular :current="currentIndex" @change="swiperChange"><swiper-item v-for="item in classList" :key="item._id"><image @click="maskChange" :src="item.picurl" mode="aspectFilla"></image></swiper-item></swiper><view class="mask" v-if="maskState"><view class="goBack" :style="{top:getStatusBarHeigth()+'px'}" @click="toBack"><uni-icons type="back" size="20" color="#fff"></uni-icons></view><view class="count">{{ currentIndex +1 }}/{{classList.length}}</view>
<script setup>
const classList = ref([]); //数据源,const currentId = ref(null) //当前点击的id,是从上一页传递过来的const currentIndex = ref(0) //当前的下标const storageClassList = uni.getStorageSync("storageClassList") || []; //获取缓存中的数据源classList.value = storageClassList.map(item => {return {...item,picurl: item.smallPicurl.replace("_small.webp", ".jpg")}})//获取传递过来的idonLoad((e) => {currentId.value = e.id;//通过findIndex获取下标currentIndex.value = classList.value.findIndex(item => item._id == currentId.value);})//这是定义的swiper的滑动事件const swiperChange = (e) => {currentIndex.value=e.detail.current;}</script>
以上就实现效果了,里面有注释,有不对的地方欢迎指出。
学海无涯苦作舟,书山有路勤为径!!!