前言
本篇文章,将对照专题案例在小程序上实现第一个功能,也就是主界面浏览卡片类型的功能。
案例的运行效果,可以扫码观看:
一、功能说明
主界面要实现的功能,主要是让用户选择感兴趣的卡片类型,点击进入浏览学习卡片。
查看卡片类型的时候,类似商品选择大类小类,在左侧栏目点击卡片大类文字项,右侧则展现该大类对应的卡片小类图片和文字。点击任意小类图片,则进入另外界面浏览该小类卡片。
二、代码实现
1.创建主界面Page
在资源管理器里创建index页面。
2.WXML
先展示下代码:
<!--index.wxml-->
<view class="container">
<scroll-view class='nav_left' scroll-y='true'>
<block wx:for="{{cateItems}}" wx:key="{{index}}">
<view class="nav_left_items {{curNav==item.Id?'active':''}}" style="background:{{curNav==item.Id?_Colourful:'#F2F2F2'}}" bindtap="switchRightTab" data-index='{{index}}' data-id="{{item.Id}}">{{item.Name}}</view>
</block>
</scroll-view>
<scroll-view class="nav_right" scroll-y="true">
<!--如果有数据,才遍历项-->
<view wx:if="{{cateItems[curIndex].Types.length>0}}">
<block wx:for="{{cateItems[curIndex].Types}}" wx:key="{{index}}">
<view class="nav_right_items">
<!--界面跳转 -->
<view id="{{item.Id}}" data-mode="{{item.ImageMode}}" bindtap="handleEnter">
<image wx:if="{{item.ImageMode == 0}}" style="border-radius: 30rpx; border: 2px solid #dddddd;" src="http://www.xxx.cn/images/type/{{item.Id}}.jpg{{item.ImageVer}}"></image>
<image wx:else style="border-radius: 30rpx; border: 2px solid #ff9999;" src="http://www.xxx.cn/images/type/{{item.Id}}.jpg{{item.ImageVer}}"></image>
<text wx:if="{{item.ImageMode == 0}}" style="color:black;">{{item.Name}}</text>
<text wx:else style="color:red;">{{item.Name}}</text>
</view>
</view>
</block>
</view>
<!--如果无数据,则显示-->
<view class="nocate" wx:else>
<text>{{showText}}</text>
</view>
</scroll-view>
</view>
其中,我们需要将卡片类型数据存放于cateItems变量,cateItems本身存放大类信息,而其中的Types结构,则存放该大类对应的小类列表。
变量的数据,通过JS文件访问服务端获取,包括卡片大类小类的Id、类别名称、排序、状态、学习模式等信息。
大类呈现的时候,通过{{curNav==item.Id?‘active’:’’}}方式,对当前选中大类赋予active的class,这样可以巧妙控制选中项的特别样式。这个例子里,选中项特别地通过_Colourful来显示随机的一些颜色。
小类呈现的时候,通过卡片学习模式类型ImageMode来控制样式显示,这里item.ImageMode == 0表示该卡片类型用普通中英文词语顺序浏览,用黑色图片边框和文字展示;否则卡片为题目方式随机浏览,用红色图片边框和文字展示。
小类的图片,通过指定服务器网站url地址进行获取显示。这些图片均保存在服务器网站空间。
2.JS
接下来我们为页面定义数据获取和操作逻辑的代码。
const app = getApp()
Page({
data: {
SessionNo: '',
cateItems: [],
curNav: 1,
curIndex: 0,
_Colourful: "#3490f2",
_Cnt: 1,
showText: "正在加载"
},
switchRightTab: function (e) {
var timestamp = Date.parse(new Date());
var date = new Date(timestamp);
let id = e.target.dataset.id,
index = e.target.dataset.index,
_cnt = date.getSeconds() % 10; // 用于生成颜色数组随机下标值
this.setData({
_Colourful: app.globalData.Colourful[_cnt],
curNav: id,
curIndex: index,
})
},
setMenu(res) {
var _cateItems = res.data;
this.setData({
cateItems: _cateItems,
showText: "持续更新中"
})
if (_cateItems.length > 0) {
// 默认加载第一个大类
this.setData({
curNav: _cateItems[0].Id,
curIndex: 0
})
}
},
onLoad: function (option) {
this.setData({
SessionNo: app.globalData.SessionNo
})
// 调用服务端GetType方法获取卡片大小类信息
wx.request({
url: 'http://www.xxx.cn/GetType.ashx',
data: {
},
method: "POST",
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success: this.setMenu.bind(this)
})
},
handleEnter: function (e) {
let selectid = e.currentTarget.id;
let imageMode = e.currentTarget.dataset.mode;
// 打开卡片浏览界面,将卡片类型Id和学习模式参数传递
wx.navigateTo({
url: '../card/card?typeid=' + selectid + '&categoryid=' + this.data.curNav + '&imagemode=' + imageMode
})
},
// 分享小程序
onShareAppMessage() {
return {
title: '宝宝卡片屋',
path: '/pages/index/index'
}
},
})
在界面加载的方法onLoad,即调用服务端GetType方法获取卡片大小类信息。
注意赋值data使数据实时在页面上更新,不能直接用=,而应该用这种形式:this.setData({ … }),让数据从逻辑层传到渲染层。
3.WXSS
对样式文件进行定义。
.container{
position:fixed;
width:100%;
height: 100%;
background-color:#FFF;
}
.nav_left{
width:25%;
height:100%;
background:#F2F2F2;
text-align:center;
position:absolute;
top:0;
left:0;
}
.nav_left .nav_left_items{
height:100rpx;
line-height:100rpx;
font-size:33rpx;
}
.nav_left .nav_left_items.active{
position:relative;
color:#fff;
font-size:36rpx;
}
.nav_right{
position:absolute;
top:0;
right:0;
width:75%;
height:100%;
background-image: linear-gradient(90deg, #f9f9f9 10%, rgba(0, 0, 0, 0) 10%),
linear-gradient(#f9f9f9 10%, rgba(0, 0, 0, 0) 10%);
background-size: 18rpx 18rpx;
}
.nav_right .nav_right_items{
float: left;
width: 48%;
text-align: center;
padding:20rpx 1% 0;
}
.nav_right .nav_right_items image{
width: 200rpx;
height: 200rpx;
}
.nav_right .nav_right_items text{
display: block;
margin-top: 5rpx;
font-size: 34rpx;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
height: 80rpx;
}
.nocate{
padding:100rpx;
text-align: center;
}
.nocate image{
width:70rpx;
height:70rpx;
}
.nocate text{
font-size:34rpx;
display:block;
color:#999;
}
/*隐藏滚动条*/
::-webkit-scrollbar{
width: 0;
height: 0;
color: transparent;
}
4.合法域名校验
默认运行上述程序时,可能会出现如下的错误:
这是因为微信小程序为了访问安全,对任何调用其他Web服务的访问,都会进行域名合法校验。需要在微信公众平台“开发管理”——“开发设置”——“服务器域名”的“request合法域名”,添加需要访问的Web服务域名,否则就会出现上面错误。这也是前面我们需要另外申请域名而不用IP地址的原因。
另外我们发现,配置的域名,都是需要https访问才可以,这样就要求在主页空间也部署上SSL证书。这个部署我们等后面讲发布小程序的章节再介绍。
那么在这里,如果仅仅是预览和调试的话,是否可以绕过这个校验呢?答案是肯定的,我们只要勾选启用项目本地配置里的“不校验合法域名、web-view(业务域名)、TLS版本以及HTTPS证书”,就可以直接使用不满足要求的Web地址进行测试。当然在最终发布时候,是一定需要这些校验的。
5.图片缓存刷新问题的解决
大家可能注意到,我在WXML文件中,图片url链接里,地址后面都会加上{{item.ImageVer}},这是应对前面也提到过的,图片缓存显示问题。
因为测试发现,如果url不变,当服务端图片有了更新,即使清除小程序的相关缓存,依然只能显示更新前的图片。这时候,我们通过在服务端数据表里定义了ImageVer字段,当图片的文件名不变但图片有更新时,通过设置ImageVer为“?” + 新的值(比如按照1,2,3相当于版本号递增进行变化),引起整个url的变化,程序就会重新到服务器抓取最新的图片文件进行显示,达到刷新的目的。
小结
经过以上操作,已经可以在模拟器或者手机预览效果了。做出了第一个界面是不是很激动,我们下一篇文章,就可以来开发卡片的浏览学习功能界面了。
专题文章链接
最详细的【微信小程序+阿里云Web服务】开发部署指引(一):准备开始
最详细的【微信小程序+阿里云Web服务】开发部署指引(二):注册微信小程序
最详细的【微信小程序+阿里云Web服务】开发部署指引(三):开通阿里云主机
最详细的【微信小程序+阿里云Web服务】开发部署指引(四):搭建服务端数据库
最详细的【微信小程序+阿里云Web服务】开发部署指引(五):实现服务端调用逻辑
最详细的【微信小程序+阿里云Web服务】开发部署指引(六):开发微信小程序的准备
最详细的【微信小程序+阿里云Web服务】开发部署指引(七):小程序项目中的文件资源
最详细的【微信小程序+阿里云Web服务】开发部署指引(八):开发小程序卡片类型呈现功能
最详细的【微信小程序+阿里云Web服务】开发部署指引(九):开发小程序卡片浏览功能
最详细的【微信小程序+阿里云Web服务】开发部署指引(十):实现发音朗读
最详细的【微信小程序+阿里云Web服务】开发部署指引(十一):开发小程序设置功能
最详细的【微信小程序+阿里云Web服务】开发部署指引(十二):开发小程序用户反馈功能
最详细的【微信小程序+阿里云Web服务】开发部署指引(十三):小程序底部菜单
最详细的【微信小程序+阿里云Web服务】开发部署指引(十四):发布小程序
最详细的【微信小程序+阿里云Web服务】开发部署指引(十五):结语