现在电商做的风生水起,各家门主都想得其红利,分一杯肥羹。无论是小程序还是移动端、web端前端页面开发都大致相同。不能只会写代码,不会梳理描述。我把JJ智能生鲜平台(以下简称JJ平台)分各个页面和模块编写,然后逐一进行分析,实现页面间交互,比如点击首页轮播图跳转到对应商品详情页等,最后附上源码。
实现效果如下:
本文主要涵盖一下内容:
- Easy Mock
- 平台首页
- 分类详情页
- 购物车
- 个人中心
- 商品详情页
- 提交订单页
- 请求并接口数据
JJ平台涉及技术:
- Easy Mock
- 小程序
- Vant Weapp(ZanUI)
- javascript
- css
1. Easy Mock
Easy Mock用来模拟数据,可以快速生成前端接口。它能够为小程序提供一个由前端完全控制的“服务端”平台,可以让小程序开发过程中,小程序的开发不会被后台的开发所阻塞。
创建项目和接口如下:
EasyMock使用教程可以参考官方文档
将项目所需要要的数据模拟好以后来开发首页,当然这一步也可以放在最后做。
1.项目结构
项目结构图如下:
2.JJ首页
首页包含navigation顶部、搜索框、轮播图、商品种类(使用商品代替了)等,搜索框和商品卡片是使用vant weapp提供的组件完成,轮播图使用小程序官方提供的组件完成。
部分wxml代码如下:
<view class='header'>
<!-- 使用vant weapp的search组件 -->
<van-search class="searchbox"
value="{{ value }}"
placeholder="新鲜荔枝"
use-action-slot="true"
bind:search="onSearch"
shape="round"
background="#eee"
>
<view slot="action" bind:tap="onSearch">搜索</view>
</van-search>
</view>
<view class='slide'>
<!-- 轮播图 -->
<swiper class='slide' autoplay='true' indicator-dots='true' indicator-color='white' circular="true" interval="2000">
<block wx:for="{{slides}}" wx:key="index">
<swiper-item>
<navigator url="../goods/goods?" open-type="switchTab">
<image mode="widthFix" src='{{item.image}}'></image>
</navigator>
</swiper-item>
</block>
</swiper>
效果如下:
3.分类详情页
详情页主要是使用小程序组件知识实现的,主要还是样式的设置。顶部按钮可以实现切换。切换的效果使用小程序提供的swiper滑动组件实现,wxml代码如下:
<!-- goods.wxml -->
<!-- by tomorrownan -->
<view class='tabbtn'>
<ul>
<li class="{{current==0 ? 'active' : ''}}" bindtap="switchCur" data-index="0">默认</li>
<li class="{{current==1 ? 'active' : ''}}" bindtap="switchCur" data-index="1" >价格</li>
<li class="{{current==2 ? 'active' : ''}}" bindtap="switchCur" data-index="2" >热销</li>
</ul>
</view>
<swiper class='goodslist' current="{{current}}" bindchange="changeCur">
<swiper-item>
<scroll-view scroll-y='{{true}}' class="scrollbox">
<!-- wx:for循环读取数据 -->
<view class='goodcart' wx:for="{{goodslist}}" wx:for-item="goodinfo" wx:key="id" data-id="{{goodinfo.id}}">
<navigator url="../detail/detail?id={{goodinfo.id}}">
<!-- 商品图片 -->
<view class='goodimg'>
<image src='{{goodinfo.pic_url}}' mode='aspectFill'></image>
</view>
<!-- 商品文字描述 -->
<view class='goodtext'>
<view class='goodname'>{{goodinfo.name}}</view>
<view class='gooddesc'>{{goodinfo.desc}}</view>
<view class='pricetype'>
<text class='goodprice'>{{goodinfo.price}}</text>
<text class='goodtype'>{{goodinfo.type}}</text>
</view>
</view>
</navigator>
</view>
</scroll-view>
</swiper-item>
<!-- 按价格排序 -->
<swiper-item>
<scroll-view scroll-y='{{true}}' class="scrollbox">
<!-- wx:for循环读取数据 -->
<view class='goodcart' wx:for="{{goodslist}}" wx:for-item="goodinfo" wx:key="index" data-id="{{goodinfo.id}}">
<navigator url="../detail/detail?id={{goodinfo.id}}">
<!-- 商品图片 -->
<view class='goodimg'>
<image src='{{goodinfo.pic_url}}' mode='widthFix'></image>
</view>
<!-- 商品文字描述 -->
<view class='goodtext'>
<view class='goodname'>{{goodinfo.name}}</view>
<view class='gooddesc'>{{goodinfo.desc}}</view>
<view class='pricetype'>
<text class='goodprice'>{{goodinfo.price}}</text>
<text class='goodtype'>{{goodinfo.type}}</text>
</view>
</view>
</navigator>
</view>
</scroll-view>
</swiper-item>
</swiper>
效果如下:
4.购物车页面
购物车页面可实现添加商品,商品数量的编辑,价格总额显示,全选与单选等购物车应有的功能。
使用微信的缓存API将添加进购物车的商品缓存下来,然后再依次读取这些数据。商品的加减和选择都是使用原生javascript实现,js购物车功能代码如下:
// 总计价格
getsumtotal : function(){
// console.log(this.data.cartItems)
var sum = 0
for (var i = 0;i<this.data.cartItems.length;i++){
if(this.data.cartItems[i].selected){
sum += this.data.cartItems[i].value * this.data.cartItems[i].price
}
}
sum = parseFloat(sum).toFixed(1)
this.setData({
total:sum
})
},
// 加
add:function(event){
// console.log(event)
// 获取购物车中商品列表
var cartItems = this.data.cartItems
// 获取商品索引
var index = event.target.dataset.index
// 获取商品数量
var count = cartItems[index].value
// 点击时数量加1
count++
// 重新赋值
cartItems[index].value = count
this.setData({
cartItems: cartItems
})
this.getsumtotal()
// 更新缓存
wx.setStorageSync("cartItems", cartItems)
},
// 减
reduce:function(event){
// 获取购物车中商品列表
var cartItems = this.data.cartItems
// 获取商品索引
var index = event.target.dataset.index
// 获取商品数量
var count = cartItems[index].value
// 商品数量大于1时点击时数量减1
if (count==1){
// 重新赋值
cartItems[index].value = 1
}else{
count--
// 重新赋值
cartItems[index].value = count
}
this.setData({
cartItems: cartItems
})
this.getsumtotal()
// 更新缓存
wx.setStorageSync("cartItems", cartItems)
},
// 删除
delete:function(event){
var cartItems = this.data.cartItems
var index = event.target.dataset.index
// 删除当前下标的商品
cartItems.splice(index,1)
if (cartItems.length===0){
wx:wx.showToast({
title: '空了,去购物',
duration: 2000
})
}
// 更新数据
this.setData({
cartItems: cartItems
})
//
this.getsumtotal();
// 更新缓存
wx.setStorageSync("cartItems", cartItems)
},
// 是否全部选中
allSelected:function(event){
var checkedAll = this.data.checkedAll
checkedAll = !checkedAll
var cartItems = this.data.cartItems
for(var i=0;i<cartItems.length;i++){
cartItems[i].selected = checkedAll
}
this.setData({
cartItems: cartItems,
checkedAll: checkedAll
})
this.getsumtotal()
},
// 单选
oneSelected:function(event){
var cartItems = this.data.cartItems
// console.log(event)
var index = event.target.dataset.index
var select = cartItems[index].selected
cartItems[index].selected = !select
this.setData({
cartItems: cartItems
})
this.getsumtotal()
// 更新缓存
wx.setStorageSync("cartItems", cartItems)
},
实现效果如下:
5.个人中心
个人中心包含登录,使用微信授权登录,由小程序API wx.getUserInfo
实现。给授权按钮绑定登录事件,如下 实现代码:
login: function() {
var self = this
// console.log(canIUse)
// 查看是否授权
wx.getSetting({
success(res) {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称
wx.getUserInfo({
success: function (res) {
console.log(res.userInfo)
self.setData({
userinfolist: res.userInfo
})
}
})
}
}
})
this.setData({
flag: false
})
}
未登录前样式如下:
6.商品详情页
商品详情页是由商品列表页点击商品跳转后的页面。主要点在于判断商品id,相等时显示对应的商品信息。底部购物车和立即购买按钮使用vant weapp提供的商品导航组件实现,使用小程序navigator导航组件设置点击立即购买会跳转到下订单页面。
wxml代码如下:
<!-- 详情页 -->
<!-- by tomorrownan -->
<view class="detailBox">
<view class="detail-list">
<scroll-view scroll-y="true" style="height:90%;">
<view class="detailPic"><image src="{{detailGood.pic_url}}"></image></view>
<view class="detailInfo">
<ul>
<li>名称 {{detailGood.name}}</li>
<li>源产品 产地 产自泰国,浙江配送</li>
<li>描述 {{detailGood.desc}}</li>
<li>价格 {{detailGood.price}}</li>
<li>规格 {{detailGood.type}}</li>
<li>评价 (15172)</li>
<li>问大家 (15172)</li>
<li>图文详情</li>
</ul>
</view>
</scroll-view>
</view>
<!-- 购物车 -->
<view>
<van-goods-action>
<van-goods-action-icon
icon="chat-o"
text="客服"
bind:click="onClickIcon"
/>
<van-goods-action-icon
icon="cart-o"
text="购物车"
bind:click="onClickIcon"
/>
<van-goods-action-button
text="加入购物车"
type="warning"
bind:click="onClickButton"
/>
<navigator url="../order/order?id={{detailGood.id}}">
<van-goods-action-button
text="立即购买"
bind:click="onClickButton"
/>
</navigator>
</van-goods-action>
</view>
</view>
效果如下:
7.提交订单页
提交订单页是点击购买时跳转后的页面,根据商品id显示对应的商品卡片,下面是一些field框,主要使用van-card、van-panel、van-field实现。
效果图如下:
8.请求并使用接口数据
请求接口使用小程序API wx.request
,在url属性设置接口的地址,这里有两点需要注意:
1.this作用域指向问题,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象,在函数内直接使用this.setData可能会报错。
2.wx.request是异步函数,如果下方有同步函数,会先执行下方的代码,所以在success中使用setData修改data中的数据为其赋值后,在下方使用可能不是是你想要的值。
解决方法:
问题1解决:使用一个新变量来承接this,例如:var self = this
。
问题2解决:使用嵌套方式,直接在success回调函数中执行你想要执行的代码。还可以使用promise方法解决。
例如商品详情页调用接口和数据方法如下:
onLoad: function (options) {
var self = this
var id = options.id
wx: wx.request({
url: 'https://www.easy-mock.com/mock/5d01eca83066922c5416c8ac/Ananfresh/goodsList',
success: function (res) {
// console.log(res.data.data)
self.setData({
detailsList: res.data.data
})
var detailData = self.data.detailsList
// console.log(detailData)
detailData.forEach(function (array) {
// console.log(array.id)
if (array.id == id) {
self.setData({
detailGood: array
})
}
})
}
})
// console.log(this.data.detailsList)
},