初学前端在小程序中使用for循环的一个优化案例
发表时间:2021-1-11
发布人:葵宇科技
浏览次数:80
作为前端的小白,已经学习了个把月了,for循环
在微信小程序中的使用在常见不过了;在获取某个官方API数据后,如何将获取的若干条数据分别不重复的放入到不同的循环当中呢?让我们看个小小的例子去体会一波。
原界面分析
界面分析
首先我们来看一下网易云音乐其中的一个界面:
这个界面其实相对来讲时比较好做的,主要就是分为两大块内容,先说中间这块-->官方榜单:左边对应的时榜单的图片,右边则是这个榜单内的歌曲,然后每行的样式都是一样的,使用for循环遍历去做会特别简便。 然后我们再看其他的一些榜单区的内容:都是一行分布3个为上方图片加下方文字的样式,这个也可以用到循环来实现。
数据分析
这里分享一下API链接:http://neteasecloudmusicapi.zhaoboy.com/toplist/detail
(如何调用API想必大家也会使用,或者也从其他的大佬的文章中学习过)
然后我们来看到获取到的数据并进行分析:
从第一张图片我们可以知道list
下获取到若干条信息,每条信息中的updateFrequency
对应该榜单更新时间,coverImgUrl
对应该榜单的图片,还有一项是tracks
也是我们需要用到(看下张图)
可以看到tracks中包含的信息就是歌单了,也就是我们官方榜单中需要用到的数据
从第三章图可以看到,从编号为4开始tracks
中的信息就为空了,也就是刚才给大家展示的原界面中只有官方
榜单需要这项信息,其他的榜单是不需要的。所以循环出的若干条数据中,我们需要将前4条放进官方榜单,而后面其他的数据放进其他的榜单当中,for循环
下我们会将所有拿到的数据都循环出来,并且样式还是一样的。而这个界面则是在同一数据下,分别用循环放到两个不同的样式当中,大家肯定都想得到,加个if判断就好了,接下来,让我们看看如何实现。
代码实现
wxml
<view class="body-view">
<loading hidden="{{hidden}}">
加载中...
</loading>
</view>
<view class="wrapper">
<!-- 上部分:榜单推荐容器 -->
<view class="ranking">
<text class="ranking-name">榜单推荐</text>
<view class="rankingbox">
<view class="rankinglist" wx:for="{{rank}}" wx:key="index">
<image class="ranking-img" src="http://www.wxapp-union.com/{{item.img}}" />
<view class="updatetime">{{item.date}}</view>
<view class="rankinglist-name">{{item.listname}}</view>
</view>
</view>
</view>
<!-- 中间部分:官方榜容器 -->
<view class="officiallist">
<text class="ranking-name">官方榜</text>
<view class="officiallistbox">
<view class="official-list" wx:for="{{list}}" wx:key="index">
<view wx:if="{{index <= 3}}">
<image class="ranking-img" src="http://www.wxapp-union.com/{{item.coverImgUrl}}" />
<view class="updatetime">{{item.updateFrequency}}</view>
<view class="ranking-des">
<block wx:for="{{item.tracks}}" wx:key="index">
<view class="songlist">
<text class="songname">{{index+1}}.</text>
<text class="songname">{{item.first}}</text>
-
<text class="songname">{{item.second}}</text>
</view>
</block>
</view>
</view>
</view>
</view>
</view>
<!-- 下部分:其他所有榜单容器循环 -->
<view class="otherranking">
<text class="otherranking-name">更多榜单</text>
<view class="otherrankingbox">
<block class="otherrankinglist" wx:for="{{list}}" wx:key="index">
<view class="other" wx:if="{{index > 3}}">
<image class="ranking-img" src="http://www.wxapp-union.com/{{item.coverImgUrl}}" />
<view class="updatetime">{{item.updateFrequency}}</view>
<view class="rankinglist-name">{{item.name}}</view>
</view>
</block>
</view>
</view>
</view>
复制代码
wxss
/* 上部分:榜单推荐容器 */
.wrapper {
width: 100%;
height: 100%;
}
.ranking {
margin: 60rpx 0 0 40rpx;
}
.rankingbox {
display: flex;
flex-wrap: wrap;
}
.rankinglist {
margin: 30rpx 30rpx 30rpx 0rpx;
}
.ranking-name {
font-size: 35rpx;
font-weight: 550;
}
.ranking-img {
width: 204rpx;
height: 204rpx;
border-radius: 10rpx;
}
.updatetime {
position: absolute;
margin-top: -45rpx;
margin-left: 15rpx;
font-size: 18rpx;
color: rgb(241, 241, 241);
}
.rankinglist-name {
font-size: 20rpx;
max-width: 180rpx;
overflow: hidden;
text-overflow: ellipsis;
}
.ranking-des {
width: 530rpx;
height: 150rpx;
margin: 0rpx 20rpx 0 20rpx;
float: right;
position: absolute;
margin-top: -200rpx;
margin-left: 210rpx;
display: flex;
flex-direction: column;
justify-content: space-around;
flex: 1 1 0%;
padding: 10px;
}
/*上部分榜单推荐和下部分其他所有榜单所用css一样*/
/*中间官方榜单部分的榜单名,图片和上部分一样*/
/* 中间部分:官方榜容器 */
.officiallist {
margin: 60rpx 0 0rpx 40rpx;
}
.officiallistbox {
margin: 30rpx 0 20rpx 0rpx;
}
.official-list {
margin: 0rpx 0 15rpx 0rpx;
}
.songlist {
max-width: 450rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.songname {
font-size: 25rpx;
}
.otherranking {
margin: 60rpx 0 0rpx 0rpx;
}
.otherrankingbox {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 10rpx 40rpx;
margin: 30rpx 0 0rpx 0rpx;
}
.otherranking-name {
margin-left: 40rpx;
font-size: 35rpx;
font-weight: 550;
}
.other {
margin-bottom: 20rpx;
}
复制代码
js部分
// const API = require('../../toplist/detail')
const app = getApp();
Page({
data: {
hidden: false, //加载是否隐藏
list: [],
rank: [
{
img: 'https://p2.music.126.net/c0iThrYPpnFVgFvU6JCVXQ==/109951164091703579.jpg',
date: '每周四更新',
listname: '云音乐欧美热歌榜',
},
{
img: 'https://p2.music.126.net/WTpbsVfxeB6qDs_3_rnQtg==/109951163601178881.jpg',
date: '每周一更新',
listname: 'iTunes榜',
},
{
img: 'https://p2.music.126.net/Zb8AL5xdl9-_7WIyAhRLbw==/109951164091690485.jpg',
date: '每天更新',
listname: '云音乐欧美新歌榜',
}
]
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.request({
url:'http://neteasecloudmusicapi.zhaoboy.com/toplist/detail',
data: {
},
header: { // 加载效果
"Content-Type": "application/json"
},
success: (res) => {
console.log(res)
this.setData({
list: res.data.list
})
if(this.data.list.length>0){
this.setData({
hidden: true
})
}
}
})
},
})
复制代码
实现效果
分享大家看到代码中,我们是通过 wx:if 去判断 index <= 3
时数据放在officiallist
这个官方榜单中,而 index > 3
时,则放在otherranking
这个其他榜单中,这样写确实也没错,也实现了功能,但是逻辑不严谨,官方数据发生变化时,又得修改代码去改变if判断的值,变化一次就得改变一次(这里说的变化是:当API数据中改变成第六或者第几条数据开始tracks中才为空,那么原来index > 3
就起不到作用,又得手动去修改这个定值)。而且这样的if判断还有一些问题,剩下没取到的数据会以空数据输出,会占用一定的位置,则又需要对css进行修改,使布局不被影响,增加了一定的麻烦。(可以具体看看调试中的显示:下图)
优化方法
简述
其实我们可以在js中进行判断,API中是只有前几条数据中的tracks
中是有歌单的数据的,后面其他的数据中的tracks
是空的,所以我们只需要从tracks
中取下手就可以。去判断tracks
何时是有数据则放在官方榜单,当tracks
中为空,则将这些数据放在其他榜单中。下面我们先看具体代码(这里我们把修改部分的代码放出来)
wxml
<!-- 官方榜 -->
<view class="official-list" wx:for="{{officialList}}" wx:key="index">
<view>
<image class="ranking-img" src="http://www.wxapp-union.com/{{item.coverImgUrl}}" />
<view class="updatetime">{{item.updateFrequency}}</view>
<view class="ranking-des">
<block wx:for="{{item.tracks}}" wx:key="index">
//这里放的还是之前的代码,block中循环的是tracks中的歌单数据,和之前的一样不用修改
</block>
</view>
</view>
</view>
复制代码
<!-- 其他榜单 -->
<block class="otherrankinglist" wx:for="{{moreList}}" wx:key="index">
<view class="other">
<image class="ranking-img" src="http://www.wxapp-union.com/{{item.coverImgUrl}}" />
<view class="updatetime">{{item.updateFrequency}}</view>
<view class="rankinglist-name">{{item.name}}</view>
</view>
</block>
复制代码
js:
// 在data 中新增加两个新的空数组
data: {
officialList: [], //新增加
moreList: [], //新增加
list: [],
rank: [
//这里还放之前的数据
],
},
onLoad: function (options) {
wx.request({
//这里还是放之前的API调用
},
// 重点:在回调函数中判断tracks中是否有数据并放入定义的数组中
success: (res) => {
const oList = res.data.list.filter(item => item.tracks.length
)
console.log(oList)
const mList = res.data.list.filter( item => !item.tracks.length
)
this.setData({
// 经过判断拿到数据后,分别对应放入之前的定义的官方榜单和其他榜单的数组中
officialList:oList,
moreList:mList,
list: res.data.list
})
}
})
},
})
复制代码
分析
修改后将 wx:if
的语句判断去掉了,在js中的data里面我们定义了两个新的空数组,officialList: []
和moreList: []
在调取API数据成功后,我们定义了一个 oList
和 mList
,并判断tracks中是否有数据,有则放在oList
,没有则放在mList
;最后分别将oList
和 mList
中的数据传给数组 officialList
和moreList
,去达到我们之前所想要的效果。我们最后去调试可以发现,不会再有多循环出来的空数组,并且数据会根据官方API数据的更新自动区别改变,请看图
总结
这里我们通过一个界面的例子,从分析到优化,虽然只是优化其中的一个逻辑,但带来的代码效果还是很显著的。作为小白的我们,从切图开始,做假数据先把界面做出来,然后去调用真数据引入。实现一个功能的办法有很多,更强的逻辑思维,和严谨的代码风格也更应该是我们追求的,也是我们小白需要慢慢改进的地方,总体来说就是去让自己做的更好。感谢各位大佬的观赏,如果有不足的地方或者有更好的想法和建议也欢迎指出哦!
作者:北秋丶
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。