做爲一個剛入門學前端的小白我來講,寫這個小程序花了不少時間,遇到了不少問題,也學到了不少,很是感謝那些幫我解決問題的老師和同窗。這個小程序主要實現的是購物車功能,有些許功能未得以實現,好比搜索功能,因爲小米有品沒有開源的api,搜索的不少數據須要本身來寫,以爲這是一項巨大的工程,而後你懂得(就沒寫搜索功能了)。項目地址。但願能給初學者一些幫助。前端
1.分享功能 利用button組件,把catchtap="shares"來點擊分享實現分享給微信好友的彈框(同時出現遮罩層),在此以前要先給包容彈框的盒子設置一個遮罩層,點擊頁面的任何一個地方遮罩層消失。 git
<view class="share-mask {{active ? 'active' : ''}}" bindtap="hideMask">
<view class="shares">
<view class="share">分享</view>
<view class="share_content">
<view class="share_left">
<button catchtap="shares" class="shares-btn" open-type="share" hover-class="none">
<image class="shareImg" src="../../../images/wechat.png"/>
<text>發送給朋友</text>
</button>
</view>
<view class="share_right">
<image class="shareImg" src="../../../images/poster.png"/>
<text>生成圖庫</text>
</view>
</view>
<view class="cancel">取消</view>
</view>
</view>
複製代碼
// 分享
toShare() {
this.setData({
active: true
})
},
// 隱藏遮罩層
hideMask() {
this.setData({
active: false
})
},
// 分享給微信好友
onShareAppMessage (options) {
return {
title:this.data.detail[0].detailOne
}
}
複製代碼
<view class="category-left">
<view wx:for="{{category}}" wx:key="{{item.id}}"
data-id="{{item.id}}" data-index="{{index}}"
class="cate-list {{ curIndex === index ? 'on' : '' }}" bindtap="switchTab" >{{item.name}}</view>
</view>
<scroll-view class="categroy-right" scroll-y scroll-into-view="{{toView}}" scroll-with-animation="{{true}}">
<view class="cate-box" id="{{detailList.id}}">
<view class="cate-banner">
<image src="{{detailList.banner}}"></image>
</view>
<view class="cate-title">
<text>{{detailList.cate}}</text>
</view>
<view class="product">
<view class="product-list" wx:for="{{detailList.detail}}" wx:key="index" wx:for-item="product">
<navigator url="#">
<image src="{{product.thumb}}" />
<view class="classname">
<text>{{product.name}}</text>
</view>
</navigator>
</view>
</view>
</view>
</scroll-view>
複製代碼
Page({
data: {
category:[],
detail: [],
detailList: {},
curIndex:0,
toView:"youpin",
},
switchTab(e){
let currentId = e.currentTarget.dataset.id
let currentIndex = e.currentTarget.dataset.index
this.setData({
detailList: this.data.detail[currentIndex],
curIndex: currentIndex
})
}
複製代碼
此頁面簡單的實現了點擊首頁的商品,購物車會顯示相關加入的商品,以及加減、全選、取消全選(點擊任意一個商品,全選消失)的功能。es6
selectAll() {
let selectAllStatus = this.data.selectAllStatus
selectAllStatus = !selectAllStatus
let carts = this.data.carts
for (let i = 0; i < carts.length; i++) {
carts[i].selected = selectAllStatus
}
this.setData({
selectAllStatus,
carts
})
this.getTotalPrice()
},
selectList (e) {
console.log(e.currentTarget.dataset.index)
let oIndex = e.currentTarget.dataset.index
let carts = this.data.carts
let test = carts[oIndex].selected
test = !test
let cartSelect = `carts[${oIndex}].selected`
this.setData({
[cartSelect]: test
})
if (this.data.carts.find(function(e) {return e.selected === false})) {
this.setData({
selectAllStatus: false
})
} else {
this.setData({
selectAllStatus: true
})
}
this.getTotalPrice()
},
getTotalPrice() {
let carts = this.data.carts
let total = 0
let totalNum = 0
for (let i = 0; i < carts.length; i++) {
if (carts[i].selected) {
total += carts[i].num * carts[i].price
totalNum += carts[i].num
}
}
this.setData({
totalPrice: total.toFixed(2),
totalNum
})
},
minusCount(e) {
// console.log(e)
const index = e.target.id
let carts = this.data.carts
// console.log(index,carts)
let num = carts[index].num
if (num <= 1) {
return
}
num = num - 1
carts[index].num = num
this.setData({
carts: carts
})
this.getTotalPrice()
},
addCount(e) {
const index = e.target.id
let carts = this.data.carts
let num = carts[index].num
num = num + 1
carts[index].num = num
this.setData({
carts: carts
})
this.getTotalPrice()
},
複製代碼
該頁面沒怎麼寫功能,大部分都是靜態的,就不過多介紹了。github
主要是點擊商品詳情頁(goods.js)的加入購物車,購物車頁面(cart.js)會顯示被加入的商品,經過把數據存儲在全局變量裏來傳值。小程序
1.首先在app.js全局變量裏定義一個carts[]數組 globalData: { cart:[] }
api
2.其次在goods.js頁面和cart.js頁面頭部定義const app = getApp();
在goods.js的addCart()方法裏app.globalData.cart = [...app.globalData.cart, this.data.detail]
用es6的解構方法,把從easy-mock裏獲取到的detail[]傳到全局變量的cart[]裏。這種寫法與push()方法不一樣在於push()方法會修改數組裏的值,而不是建立一個新的數組。數組
3.最後在cart.js的onShow生命週期裏設置購物車的數據源,即獲取goods.js在app.js裏的cart[]緩存
this.setData({
hasGoods: true,
carts: app.globalData.cart
})
複製代碼
首頁跳轉到商品詳情頁時,經過每一個商品的id來跳轉bash
// pages/index/index.js
// 去到商品詳情頁
toLists:function(e) {
// console.log(e)
let id = e.currentTarget.dataset.id
wx.navigateTo({
url: `/pages/goods/goods/goods?id=${id}`
})
}
複製代碼
在商品詳情頁把商品的id賦值給商品的index來設置數據源微信
// pages/goods/goods.js
onLoad: function (options) {
const id = options.id
this.setData({
index: id
})
}
複製代碼
如:/pages/goods/goods/goods?id=${id}
,這裏應注意下,若是參數要傳的值是一條對象的話,咱們都知道小程序裏是不支持傳對象的,此時把值傳過去的時候應該用JSON.stringify()把對象轉爲字符串,拿到值的時候應該用JSON.parse()把字符串轉爲對象。
onShow () {
let self = this
wx.request({
url:'https://www.easy-mock.com/mock/5d077b333780f05f8385d2c1/xiaoMi_youPin/goods_detail',
success(res){
console.log(res)
self.setData({
goods:res.data.data.goods
})
self.setData({
sum: self.data.goods[0].goodsPrice + self.data.goods[0].carriage - self.data.goods[0].discounts
})
}
})
}
複製代碼
這裏的合計是寫在onShow聲明週期裏的,我想說的是應該注意計算合計與請求接口數據會產生異步問題, 應該把計算合計另外放在self.setData({})
裏,並放在請求接口數據的self.setData({})
下面,由於請求接口數據的時間大於計算合計的時間,必需要拿到數據後才能計算合計。這兩個不能放在同一個self.setData({})
裏,不然得不到合計的值,以下代碼是不正確的
self.setData({
goods:res.data.data.goods,
sum: self.data.goods[0].goodsPrice + self.data.goods[0].carriage - self.data.goods[0].discounts
})
複製代碼
//pages/goods/addressList/addressList.js
Page({
data: {
addressList:[]
},
onLoad: function (options) {
var arr = wx.getStorageSync('addressList') || [];
console.info("緩存數據:" + arr);
// 更新數據
this.setData({
addressList: arr
});
},
onShow: function () {
this.onLoad();
},
addAddress:function(){
wx.navigateTo({
url: '../../goods/address/address'
});
},
/* 刪除item */
delAddress: function (e) {
this.data.addressList.splice(e.target.id.substring(3), 1);
// 更新data數據對象
if (this.data.addressList.length > 0) {
this.setData({
addressList: this.data.addressList
})
wx.setStorageSync('addressList', this.data.addressList);
} else {
this.setData({
addressList: this.data.addressList
})
wx.setStorageSync('addressList', []);
}
}
})
複製代碼
//pages/goods/address/address.js
var area = require('../../../utils/area.js');
var areaInfo = []; //全部省市區縣數據
var provinces = []; //省
var provinceNames = []; //省名稱
var citys = []; //城市
var cityNames = []; //城市名稱
var countys = []; //區縣
var countyNames = []; //區縣名稱
var value = [0, 0, 0]; //數據位置下標
var addressList = null;
Page({
data: {
transportValues: ["收貨時間不限", "週六日/節假日收貨", "週一至週五收貨"],
transportIndex: 0,
provinceIndex: 0, //省份
cityIndex: 0, //城市
countyIndex: 0, //區縣
provinceNames: ["江西省","北京省"]
},
onShow: function() {
var that = this;
area.getAreaInfo(function(arr) {
areaInfo = arr;
//獲取省份數據
that.getProvinceData();
});
},
// 獲取省份數據
getProvinceData: function() {
var that = this;
var s;
provinces = [];
provinceNames = [];
var num = 0;
for (var i = 0; i < areaInfo.length; i++) {
s = areaInfo[i];
if (s.di == "00" && s.xian == "00") {
provinces[num] = s;
provinceNames[num] = s.name;
num++;
}
}
that.setData({
provinceNames: provinceNames
})
that.getCityArr();
that.getCountyInfo();
},
// 獲取城市數據
getCityArr: function(count = 0) {
var c;
citys = [];
cityNames = [];
var num = 0;
for (var i = 0; i < areaInfo.length; i++) {
c = areaInfo[i];
if (c.xian == "00" && c.sheng == provinces[count].sheng && c.di != "00") {
citys[num] = c;
cityNames[num] = c.name;
num++;
}
}
if (citys.length == 0) {
citys[0] = {
name: ''
};
cityNames[0] = {
name: ''
};
}
var that = this;
that.setData({
citys: citys,
cityNames: cityNames
})
console.log('cityNames:' + cityNames);
that.getCountyInfo(count, 0);
},
// 獲取區縣數據
getCountyInfo: function(column0 = 0, column1 = 0) {
var c;
countys = [];
countyNames = [];
var num = 0;
for (var i = 0; i < areaInfo.length; i++) {
c = areaInfo[i];
if (c.xian != "00" && c.sheng == provinces[column0].sheng && c.di == citys[column1].di) {
countys[num] = c;
countyNames[num] = c.name;
num++;
}
}
if (countys.length == 0) {
countys[0] = {
name: ''
};
countyNames[0] = {
name: ''
};
}
console.log('countyNames:' + countyNames);
var that = this;
that.setData({
countys: countys,
countyNames: countyNames
})
},
bindTransportDayChange: function(e) {
console.log('picker country 發生選擇改變,攜帶值爲', e.detail.value);
this.setData({
transportIndex: e.detail.value
})
},
bindProvinceNameChange: function(e) {
var that = this;
console.log('picker province 發生選擇改變,攜帶值爲', e.detail.value);
var val = e.detail.value
that.getCityArr(val); //獲取地級市數據
that.getCountyInfo(val, 0); //獲取區縣數據
value = [val, 0, 0];
this.setData({
provinceIndex: e.detail.value,
cityIndex: 0,
countyIndex: 0,
value: value
})
},
bindCityNameChange: function(e) {
var that = this;
console.log('picker city 發生選擇改變,攜帶值爲', e.detail.value);
var val = e.detail.value
that.getCountyInfo(value[0], val); //獲取區縣數據
value = [value[0], val, 0];
this.setData({
cityIndex: e.detail.value,
countyIndex: 0,
value: value
})
},
bindCountyNameChange: function(e) {
var that = this;
console.log('picker county 發生選擇改變,攜帶值爲', e.detail.value);
this.setData({
countyIndex: e.detail.value
})
},
saveAddress: function(e) {
var consignee = e.detail.value.consignee;
var mobile = e.detail.value.mobile;
var transportDay = e.detail.value.transportDay;
var provinceName = e.detail.value.provinceName;
var cityName = e.detail.value.cityName;
var countyName = e.detail.value.countyName;
var address = e.detail.value.address;
console.log(transportDay + "," + provinceName + "," + cityName + "," + countyName + "," + address); //輸出該文本
var arr = wx.getStorageSync('addressList') || [];
console.log("arr,{}", arr);
addressList = {
consignee: consignee,
mobile: mobile,
address: provinceName + cityName + countyName+address,
transportDay: transportDay
}
arr.push(addressList);
wx.setStorageSync('addressList', arr);
wx.navigateBack({ })
}
})
複製代碼
這個小程序做爲我學前端以來寫的第一個項目,寫的過程是漫長的,同時也是痛並快樂着的。但願能給那些初寫小程序商城的同窗們一些幫助,畢竟我剛開始寫這個小程序的時候是迷茫的,不知如何下手。以爲寫得還ok的話,可不能夠動動大家的小拇指給我點個贊呢!如有哪寫得不足得地方能夠在下面的評論區附上大家的建議。最後再加一句,我是2020屆的畢業生,即將面臨實習的壓力,有哪位大佬能夠稍微關照下嘛。