微信小程序:九宫格列表,if条件渲染及本地数据缓存(仿XX评分首
本文主要是小程序基础知识学习,这次主要是学习了网络请求数据,以及基础样式类似九宫格的滑动列表实现.
1. 顶部导航栏搜索框的实现
顶部导航栏底色为绿色,有一个白色的搜索框以及搜索图片,搜索文字等.
<view class="header">
<view class="searchwrapper">
<image class="searchImage" src="/assets/imgs/ic_search.png" />
<text class="title">搜索</text>
</view>
</view>
.main .header {
display: flex;
align-items: center;
background-color: #66B961;
height: 80rpx;
width: 100%;
}
.header .searchwrapper{
background-color: #ffffff;
width: 93%;
height: 70%;
margin: auto;
border-radius: 10rpx;
display: flex;
justify-content: center;
align-items: center;
}
.searchwrapper .searchImage{
width: 30rpx;
height: 30rpx;
margin-right: 5rpx;
}
.searchwrapper .title{
font-size: 25rpx;
color: #B2B2B2;
}
实现效果
2. 影片九宫格列表搭建
九宫格列表的搭建思路是先将单个的item搭建出来,单个item的主要元素有电影图片,以及电影名,评分图片,评分等内容:
实现单个的item后配合scroll-view使用scroll-view官方文档,关于scroll-viewde的使用,有以下注意点:
-
设置scroll-view滚动方向:
image.png
2.单个的item在布局的时候如果使用flex布局,则默认是块级元素(独占整行),需要设置item的布局为inline-flex(行内元素),并设置scroll-view允许换行:
.items{
/* display: flex;
overflow-x: auto; 不使用scroll-view的时候可以设置overflow-x为auto,也可以实现横向滑动 */
white-space: nowrap; /*设置scroll-view允许换行*/
height: 328rpx;
}
.items .item{
display: inline-flex; /*设置item为行内元素*/
padding-left: 30rpx;
flex-direction: column;
width: 180rpx;
}
wxml中的实现代码:
<scroll-view scroll-x="true" class="items">
<view class="item" wx:key="unique" wx:for="{{ row.movies }}" wx:for-item="movie">
<image class="movieImage" src="{{movie.images.large}}"/>
<view class="title">{{movie.title}}</view>
<view class="bottom">
<block wx:if="{{movie.stars}}">
<view class="stars">
<image wx:for="{{movie.stars.on}}" class="star" wx:key="unique" src="/assets/imgs/rating_star_small_on.png"/>
<image wx:for="{{movie.stars.half}}" class="star" wx:key="unique" src="/assets/imgs/rating_star_small_half.png"/>
<image wx:for="{{movie.stars.off}}" class="star" wx:key="unique" src="/assets/imgs/rating_star_small_off.png"/>
</view>
<view class="score">{{movie.rating.average}}</view>
</block>
<block wx:else>暂无评分</block>
</view>
</view>
</scroll-view>
2.1 if条件渲染的使用
在判断某种条件成立的时候,使用到wx:if条件来实现渲染不同的元素;wx:if的使用方式主要有两种,一种是通过添加到view标签中使用,一种是使用block标签: 条件渲染小程序官方文档
- view wx:if
在框架中,使用 wx:if="" 来判断是否需要渲染该代码块:
<view wx:if="{{condition}}"> True </view>
也可以用 wx:elif 和 wx:else 来添加一个 else 块:
<view wx:if="{{length > 5}}"> 1 </view>
<view wx:elif="{{length > 2}}"> 2 </view>
<view wx:else> 3 </view>
- block wx:if
因为 wx:if 是一个控制属性,需要将它添加到一个标签上。如果要一次性判断多个组件标签,可以使用一个 <block/> 标签将多个组件包装起来,并在上边使用 wx:if 控制属性。
<block wx:if="{{true}}">
<view> view1 </view>
<view> view2 </view>
</block>
注意:block标签并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性
3 网络请求数据及处理
在获取某些接口的时候可能需要先获取位置信息,通过微信官方wx.getLocation可以获取到用户当前的经纬度信息,同时使用百度地图通过经纬度可以获取到城市名,邮编,附近酒店,影院等信息;获取位置信息可以参考另一篇文章:获取位置信息链接
在.js文件中,datas直接用于存放请求回来的数据,在发送网络请求以后,请求成功给当前的datas赋值,并刷新当前页面:
/**
* 页面的初始数据
*/
data: {
allMovies:[
{
title:'影院热映',
url:'v2/movie/in_theaters',
movies:[]
},
{
title:'新片榜',
url:'v2/movie/new_movies',
movies:[]
},
{
title:'口碑榜',
url:'v2/movie/weekly',
movies:[]
},
{
title:'北美票房榜',
url:'v2/movie/us_box',
movies:[]
},
{
title:'Top250',
url:'v2/movie/top250',
movies:[]
}
]
},
我当前仿写的页面需要发送5次请求,其中第一次请求需要先获取城市信息,其它4次请求不需要城市信息作为参数,
在实际开发中,每次请求回来的数据,movies对应的movie路径,并不一样,这时候可以使用||语法,前面条件成立,则返回前面的作为movie,前面的不存在,则返回后面条件对应的路径下的movie;
onLoad: function (options) {
this.getCity((city)=>{
this.loadData(0,{city:city});
});
this.loadData(1);
this.loadData(2);
this.loadData(3);
this.loadData(4);
},
loadData:function(idx,param){
let obj = this.data.allMovies[idx];
wx.request({
url: wx.db.url(obj.url),
data: param,
header: {'content-type':'json'},
success: (result) => {
let items = result.data.subjects;
obj.movies = [];
for (let i = 0; i <items.length; i++ ){
let movie = items[i].subject || items[i];
this.upDateStars(movie);
obj.movies.push(movie);
}
this.setData(this.data);
console.log(this.data);
},
fail: () => {},
complete: () => {}
});
},
如上图代码请求成功后数据打印示例:
image.png
刷新当前页面,使用:
this.setData(this.data);
调用此方法会自动通过datas里面的数据刷新当前页面.
3.1 九宫格的实现
前面在实现了单行的items的布局,以及横向滑动的操作,要实现多个items,可以在items的标签上添加一个for循环来实现,for循环的次数为datas中allMovies的length,具体的示例代码如下:
<view class="row" wx:key="unique" wx:for="{{ allMovies }}" wx:for-item="row">
<view class="top">
<text class="title">{{row.title}}</text>
<view class="more">
<view class="moretitle">查看更多</view>
<view class="arrow"></view>
</view>
</view>
<scroll-view scroll-x="true" class="items">
<view class="item" wx:key="unique" wx:for="{{ row.movies }}" wx:for-item="movie">
<image class="movieImage" src="{{movie.images.large}}"/>
<view class="title">{{movie.title}}</view>
<view class="bottom">
<block wx:if="{{movie.stars}}">
<view class="stars">
<image wx:for="{{movie.stars.on}}" class="star" wx:key="unique" src="/assets/imgs/rating_star_small_on.png"/>
<image wx:for="{{movie.stars.half}}" class="star" wx:key="unique" src="/assets/imgs/rating_star_small_half.png"/>
<image wx:for="{{movie.stars.off}}" class="star" wx:key="unique" src="/assets/imgs/rating_star_small_off.png"/>
</view>
<view class="score">{{movie.rating.average}}</view>
</block>
<block wx:else>暂无评分</block>
</view>
</view>
</scroll-view>
</view>
注意的小细节:
- 电影名过长显示省略号处理:固定item的宽度,并设置overflow和text-overflow:
.items .item{
display: inline-flex;
padding-left: 30rpx;
flex-direction: column;
width: 180rpx;
}
.items .title{
font-size: 30rpx;
width: 100%;
font-weight: bold;
overflow: hidden; /*超出部分直接剪切*/
text-overflow: ellipsis;/*超出部分显示省略号*/
}
- 在电影信息还未加载出来的时候先添加占位高度,实现较为简单,将row的高度直接写死;
- 星级stas需要先处理数据,实现的方式较多,然后根据自己的计算逻辑,在image标签中直接使用wx:for就可以实现星级的显示.
实现效果如下:
image.png3.2 本地数据的缓存及读取
在获取网络氢气的数据以后,可以通过微信的wx.setStoreage和wx.getStorage来实现,用一个key值对应存储的数据: 数据缓存用法官方文档
将数据存储在本地缓存中指定的 key 中。会覆盖掉原来该 key 对应的内容。除非用户主动删除或因存储空间原因被系统清理,否则数据都一直可用。单个 key 允许存储的最大数据长度为 1MB,所有数据存储上限为 10MB。
// 将movies数组缓存到本地
wx.setStorage({
key: obj.title,
data: obj.movies
});
//读取
loadLocalData: function() {
for (let index = 0; index < this.data.allMovies.length; index++) {
let obj = this.data.allMovies[index];
obj.movies = wx.getStorageSync(obj.title);
}
this.setData(this.data);
},
数据的存储分为两种类型,同步和异步:
- wx.setStorage:异步存储数据,数据存储完了执行后续操作;
- wx.setStorageSync: 同步存储数据,数据存储同时执行后续操作;
wx.setStorage({
key:"key",
data:"value"
})
try {
wx.setStorageSync('key', 'value')
} catch (e) { }
- wx.getStorage:异步读取储数据,数据存储完了执行后续操作;
- wx.getStorageSync: 同步读取数据,数据存储同时执行后续操作;
wx.getStorage({
key: 'key',
success (res) {
console.log(res.data)
}
})
try {
var value = wx.getStorageSync('key')
if (value) {
// Do something with return value
}
} catch (e) {
// Do something when catch error
}
总结
本文主要实现了通过wx:for循环,和scroll-view的组合使用,实现了九宫格的逻辑,数据处理及存储等,实践出真知,在很多想起来实现很简单的东西,在写代码的时候会发现原来是这样,所以,不要放过任意一个细节,细水长流.