最近在学习微信小程序,看了很多相关文档,以及一些大佬的文章,决定来练练,下面是仿照华为商城来实现其相应功能。代码没有很高深的地方,适合小程序初学者来相互学习借鉴。
前期准备
-
有html、css、javascript基础,了解es6的一些语法,知道小程序开发步骤,详见微信小程序开发文档
-
如果你想很完整的把一个项目仿照下来,一些图片资源是必不可少的,那么如何获取图片资源呢?这里我看到大佬的一篇文章 两步快速获取微信小程序源码 可以获取到 源码和图片,具体操作步骤就不一一解释了,作者写的很清楚。当然像我这样的菜鸟源码还是看不太懂的,只能用它的一些图片资源。不过有了这些图片我已经相当满足了,哈哈。。。
-
有了图片还需要数据,利用easy-mock制作假数据,可以自己把需要的数据写下来,那么怎么获取这些数据呢,最简单的方法就是直接通过wx.request请求数据,不过一般都会对这个方法进行封装,下面来看看最简单的数据请求
onReady: function () {
wx.request({
url:'https://www.easy-mock.com/mock/5b122f9f8cd63333d30a6c8b/mobile',
success:(res)=>{
this.setData({
theme:res.data
})
// console.log(res.data);
}
})
}
关于功能
下面就来说说我的一些功能实现吧
首页效果

- 在html中
- scroll-view竖向滚动必须设置scroll-y="true" style="height: 200rpx;" 必须..
- style="height: 200rpx;" 必须为200rpx/200px 不能用百分号
- 在js中
- "toView","scrollTop"必须设置值
- "scrollTop": 0,必须为数值
详情页介绍
详情页数据信息比较多,主要实现各个功能的数据绑定
- 功能一

主要监听swiper属性current的改变,绑定bindchange事件,举例说明
//index.html
<swiper class='sw-tu' circular="true" current="0" bindchange='onSlideChangeEnd'>
<swiper-item class="sw-tuone" wx:for="{{list.img2}}">
<image class='sw-photo' src="{{item}}" />
</swiper-item>
</swiper>
//index.js
data: {
index: 1,
},
onSlideChangeEnd: function (e) {
var that = this;
that.setData({
index: e.detail.current + 1
})
},
- 功能二

根据你选择的商品属性跳转到订单页,同时计算商品总价,通过url带参数把数据传递到订单页
<view class="num">
<text>数量</text>
<view class="count-content">
<view class="count-down {{grey?'on':''}}" bindtap="minusCount" data-index="{{index}}">-</view>
<view class="count-num">{{num}}</view>
<view class="count-add {{grey1?'on':''}}" bindtap="addCount" data-index="{{index}}">+</view>
</view>
</view>
// 购买数量减
minusCount(){
let num = this.data.num;
if(num <= 2){
this.setData({
grey:true, //当数量到一时就不能再减少了,按钮变成灰色
num:1
})
return;
}
num--;
this.setData({
grey:false,
grey1:false,
num,
totalPrice:this.data.onePrice*num //计算总价
})
},
// 购买数量加
addCount(){
let num = this.data.num;
let totalNum = this.data.product[0].num;
console.log(totalNum);
if(num >= totalNum){
this.setData({
grey1:true, //到商品库存量时不能再增加
totalPrice:this.data.onePrice*num
})
return;
}
num++;
this.setData({
num,
grey:false,
grey1:false,
totalPrice:this.data.onePrice*num
})
},
//点击立即购买按钮,将所选择的参数传递到订单页面
primary(){
wx.navigateTo({
url: `/pages/order/order?num=${this.data.num}&title=${this.data.product[0].title}&price=${this.data.product[0].price}&totalPrice=${this.data.totalPrice}`
})
},
- 功能三

<view wx:for="{{comments}}" wx:key="index" class="user_comment">
<view class="user_info">
<image class="avatar" src="{{item.avatar}}"/>
<view class="tel">{{item.tel}}</view>
<view class="star">
<image src="/image/icon_star_red.png"></image>
<image src="/image/icon_star_red.png"></image>
<image src="/image/icon_star_red.png"></image>
<image src="/image/icon_star_red.png"></image>
<image
src="/image/icon_star_red.png"></image>
</view>
</view>
<view class="content">{{item.content}}</view>
<view class="time">{{item.time}}</view>
</view>
<view class="loading" hidden="{{noLoading}}">
上拉加载更多评论</view>
<image class="loadingImage"src="/image/loading.gif" hidden="{{noLoadingImage}}"></image>
<view class="no-more" hidden="{{hasMore}}">暂时没有更多评论</view>
onReachBottom(){
let {currentPage,totalPage,noLoading,noLoadingImage}=this.data;
//利用es6语法解构赋值
// console.log(currentPage,totalPage,noLoading,noLoadingImage);
if(currentPage >= totalPage){
this.setData({
hasMore:false
})
return;
}
currentPage ++;
this.setData({
noLoading:false,
noLoadingImage:false
})
wx.request({
url: 'https://www.easy-mock.com/mock/5b129d3c791ed91ba99b116c/detail',
success: (res)=>{
const comments =[...this.data.comments,...res.data.comments];
this.setData({
comments,
noLoading:true,
noLoadingImage:true,
currentPage
})
}
})
}
cuurentpage即为当前请求数据时第几页,每请求一次currentPage++,totalpage表示总页数,hasMore用于显示暂时没有评论了,noLoading由于显示上拉加载更多评论。当我们网络请求数据成功后,将currentPage设为1,当currentPage<totalPage时,noLoading设为false,显示上拉加载更多数据,当currentPage>totalPage是显示没有更多数据可以加载,noLoading为true,hasMore为false显示没有更多评论。
地址信息管理

主要实现对地址的增加修改和删除功能
利用表单实现对输入数据的提交,注意表单每项都要有name属性才能获取到表单数据,同时提交表单时对各项数据进行校验
formSubmit: function(e) {
var warn ="";
var that = this;
var flag = false;
if(!e.detail.value.name){
warn = "请填写您的姓名!";
}else if(!e.detail.value.tel){
warn = "请填写您的手机号!";
}else if(!(/^1(3|4|5|7|8)\d{9}$/.test(e.detail.value.tel))){
warn = "手机号格式不正确";
}else if(!e.detail.value.addre){
warn = "请选择您的所在区域";
}else if(!e.detail.value.door){
warn = "请输入您的具体地址";
}else{
flag=true;
wx.redirectTo({
url: '../addressList/addressList?tel='+e.detail.value.tel+"&addre="+that.data.addreRange[e.detail.value.addre]+"&door="+e.detail.value.door+"&name="+e.detail.value.name+"&flag="+flag+"&addrevalue="+e.detail.value.addre
//后面跟的是需要传递到下一个页面的参数
});
// console.log("传过去的地址下标是多少?"+e.detail.value.addre)
}
if(flag==false){
wx.showModal({
title: '提示',
content:warn
})
}
},
在订单列表项可以点击右边的修改项,进入修改列表,在修改项中通过订单列表中传递过来的数据可以选择修改、删除或者保存地址
//获取传过来的数据
onLoad: function(options) {
this.setData({
name:options.name,
tel:options.tel,
addreValue:options.addrevalue,
door:options.door,
index:options.index
})
},
关于地区选择,利用picker组件实现
//html
<view class="item">
<text>所在地区</text>
<view class="right">
<picker name="addre" class="addre" value="{{addreValue}}" range="{{addreRange}}" bindchange="addrePickerBindchange">
{{addreRange[addreValue]}}
</picker>
</view>
</view>
//js
data:{
addreValue:0,
addreRange:[江西省赣州市','江西省南昌市','江西省上饶市','江西省抚州市','江西省宜春市','江西省九江市'],
}
addrePickerBindchange:function(e){
this.setData({
addreValue:e.detail.value //获取数组下标,最后把下标放入addreRange[e.detail.value.addre],取得值
})
订单列表项需要判断是从哪个选项跳转过来的,如果是删除项,则需要获取删除项的下标,利用数组的splice方法删除如果是从修改项过来,同样需要获取的修改项的下标,同时修改的数据也需要传递过来
//订单列表项
var index = 0;
var list=[];
Page({
data:{
list:[],
},
onLoad: function(options) {
var flag=false;//判断是从哪个页面跳转过来
var sign = 0//判断从修改页面中的保存还是删除按钮过来,保存为1,删除为2
flag =options.flag;
sign = options.sign;
if (flag) {
list.push({
"index":index++,
"name":options.name,
"tel":options.tel,
"addre":options.addre+options.door,
"image":"../../image/uncheck.png",
"addrevalue":options.addrevalue,
"door":options.door
})
this.setData({
list
})
};
if(sign=='1'){
// console.log("我是从修改页面过来的"+options.addrevalue)
list[options.index].name=options.name;
list[options.index].tel=options.tel;
list[options.index].addre=options.addre+options.door;
list[options.index].addrevalue=options.addrevalue;
list[options.index].door=options.door;
this.setData({
list
})
};
// 删除页面过来
if(sign=='2'){
list.splice(options.index, 1);
this.setData({
list
})
}
},
addAddre:function(e){
wx.navigateTo({
url: '../addressAdd/addressAdd'
})
},
toModifyAddre:function(e){
// console.log("选中的电话"+e.currentTarget.dataset.addrevalue);
// console.log("选中的index"+e.currentTarget.dataset.index)
wx.navigateTo({
url: '../addressEdit/addressEdit?name='+ e.currentTarget.dataset.name+"&tel="+e.currentTarget.dataset.tel+"&addrevalue="+e.currentTarget.dataset.addrevalue+"&door="+e.currentTarget.dataset.door+"&index="+e.currentTarget.dataset.index
})
},
toSelectAddr:function(e){
for(var i = 0;i<this.data.list.length;i++){
if(i==e.currentTarget.dataset.index){
list[e.currentTarget.dataset.index].image = "../../image/radio_selected.png"}
else{
list[i].image = "../../image/uncheck.png"
}
}
wx.navigateTo({
url: '../order/order?name='+ e.currentTarget.dataset.name+"&tel="+e.currentTarget.dataset.tel+"&addre="+e.currentTarget.dataset.addre+"&flag="+true
});
}
})
最后知识总结
-
关于页面传值,方法各异,具体实例请点击这里
- wx.navigateTo和wx.redirectTo通过url带参传递数据
- wx.switchTab进行跳转,但是switchTab不可以传递url参数,后面提供了wx.reLaunch函数。
- wx.getStorage获取本地缓存数据
- 在app.js配置全局数据app.globalData获取全局数据
- wx.request获取第三方服务器数据
- 通过event.currentTarget.dataset获取我们自定义的变量
- 接收上一页面传递过来的数据的页面通过onLoad事件的options参数接收数据
-
数据缓存 实例请点击这里
- wx.setStorage(wx.setStorageSync)来设置缓存
- wx.getStorage(key) 获取缓存
- wx.clearStorage() 清理本地数据缓存
- wx.removeStorage(OBJECT) 从本地缓存中异步移除指定 key
- localStorage 是永久存储的
小程序还有很多不足,见谅哈~
写得不好,也留个赞呗
