模仿淘宝写了一个小程序,主要目的还是练手并且以页面效果为主,写法肯定也会有更好的,后续继续加强。
关于页面的类似九宫格布局,请前往:Flex实现九宫格布局
登录页面的话,就直接点登录进入到首页了,没有做过多的交互。
其中做比较多的交互是购物车,应数据的形式做出的交互,实际的项目中可能会有更好的数据形式,产品数增减全选合计等,事件传参比较多;
下面以购物车为例,贴上购物车的部分js 代码,里面有个“监听”是否勾选和计数的函数(watchSelected),实则就是每操作一次就是调用一次该函数查询一遍,Vue的话就可以直接用watch监测Vue实例上的数据变化。
data: {
shopList: {
'001': [{
id: '1',
shopTitle: '妙竹放碗架子餐具架双层厨房沥水碗架楠竹碗碟架收纳沥水架沥碗架',
shopImage: '/images/order/orderList_06.png',
spec: ['16格带接水盘', '适合深口盘子'],
number: 1,
maxNumber: 4,
unitPrice: 2,
selected: false,
},
{
id: '2',
shopTitle: '妙竹放碗架子餐具架双层厨房沥水碗架楠竹碗碟架收纳沥水架沥碗架',
shopImage: '/images/order/orderList_06.png',
spec: ['16格带接水盘', '适合深口盘子'],
number: 2,
maxNumber: 6,
unitPrice: 3,
selected: false,
},
],
'002': [{
id: '3',
shopTitle: '妙竹放碗架子餐具架双层厨房沥水碗架楠竹碗碟架收纳沥水架沥碗架',
shopImage: '/images/order/orderList_06.png',
spec: ['16格带接水盘', '适合深口盘子'],
number: 1,
maxNumber: 5,
unitPrice: 4,
selected: false,
},
{
id: '4',
shopTitle: '妙竹放碗架子餐具架双层厨房沥水碗架楠竹碗碟架收纳沥水架沥碗架',
shopImage: '/images/order/orderList_06.png',
spec: ['16格带接水盘', '适合深口盘子'],
number: 3,
maxNumber: 5,
unitPrice: 5,
selected: false,
},
]
},
storeList: {
'001': [{
selectStore: false,
storeName: '罗意威',
storeType: '1',
}, ],
'002': [{
selectStore: false,
storeName: '罗意威1',
storeType: '0',
}, ]
},
handleAll: function(e) { //是否全选按钮
let selecedall = e.currentTarget.dataset.selecedall,
shopList = this.data.shopList,
storeList = this.data.storeList,
selectedText;
if (selecedall) {
selectedText = "反选";
} else {
selectedText = "全选";
}
for (let i of Object.keys(shopList)) { //是否商品勾选
for (let j of shopList[i]) {
j.selected = !selecedall;
}
}
for (let i of Object.keys(storeList)) { //是否勾选店铺
for (let j of storeList[i]) {
j.selectStore = !selecedall;
}
}
this.setData({
shopList: shopList,
storeList: storeList,
selectedAll: !selecedall,
selectedText: selectedText
})
this.watchSelected();
},
watchSelected: function() { //监听各选项是否勾选并结算
let shopList = this.data.shopList,
storeList = this.data.storeList,
shopListLength = this.data.shopListLength,
sum = 0,
length = 0,
key,
selectAll = false;
for (let i of Object.keys(shopList)) { //循环商品
let shopLength = shopList[i].length,
count = 0,
selectStore = `storeList.${i}[0].selectStore`;
for (let j of shopList[i]) {
if (j.selected) { //如果勾选则累计
sum += j.unitPrice * j.number;
++length; //计算已勾选商品数
++count; //计算某个店铺已勾选的商品数
}
}
if (count == shopLength) { //购物车的商品数和已勾选的商品数相等的情况下,则勾选店铺按钮,否则不勾选;
this.setData({
[selectStore]: true
})
} else {
this.setData({
[selectStore]: false
})
}
}
if (length == shopListLength) { //如果已勾选的商品数和购物车总商品数相等,则勾选“全选”,否则不勾选
this.setData({
selectedAll: true,
selectedText: "反选"
})
} else {
this.setData({
selectedAll: false,
selectedText: "全选"
})
}
this.setData({ //设置已勾选商品总价和件数
totalPrice: sum,
selectNum: length
})
},
以下的HTML代码为购物车的商品循环事例:
<view class="shop-list">
<view class="shop-view" wx:for="{{shopList}}" wx:for-item="value" wx:for-index="shopIndex" wx:key="shopkey">
<view wx:for="{{storeList}}" wx:for-item="item" wx:for-index="storeIndex" wx:key="key">
<view wx:if="{{shopIndex===storeIndex}}">
<view class="view-top" wx:for="{{storeList[storeIndex]}}" wx:for-item="storeitem" wx:key="*this">
<text class="iconfont {{storeitem.selectStore?'icon-xuanzhong':'icon-xuanzhong1'}} select-store" bindtap="selectStore" data-id="{{storeIndex}}" data-selected="{{storeitem.selectStore}}"></text>
<text class="iconfont {{storeitem.storeType=='1'?'icon-tianmao':'icon-dianpu'}} store-type"></text>
<text class="store-name">{{storeitem.storeName}}</text>
<text class="arrows">></text>
</view>
</view>
</view>
<view class="product" wx:for="{{shopList[shopIndex]}}" wx:for-index="index" wx:key="prokey">
<text class="{{item.selected?'icon-xuanzhong':'icon-xuanzhong1'}} iconfont select-pro" bindtap="handleSelect" data-selected="{{item.selected}}" data-index="{{index}}" data-key="{{shopIndex}}"></text>
<view class="pro-view">
<image class="pro-image" src="{{item.shopImage}}"></image>
<view class="pro-content">
<navigator class="pro-title">{{item.shopTitle}}</navigator>
<view class="spec-view">
<text class="pro-spec" wx:for="{{item.spec}}" wx:key="*this">{{item}}</text>
</view>
<view class="pro-nums">
<text class="pro-price">¥{{item.unitPrice}}</text>
<view class="pro-btn">
<text bindtap="handleMinus" data-arr="{{item}}" data-key="{{shopIndex}}" data-index="{{index}}">-</text>
<input class="pro-num" value="{{item.number}}" bindinput="watchSearchInput" data-maxnumber="{{item.maxNumber}}" data-key="{{shopIndex}}" data-index="{{index}}"></input>
<text bindtap="handleAdd" data-arr="{{item}}" data-key="{{shopIndex}}" data-index="{{index}}">+</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
当设置变量数据时,需要拼接后,然后用[ ]括起来;
例如:
selectStore = `storeList.${i}[0].selectStore`;
this.setData({
[selectStore]: true
})
下面是整体的效果: