小(xiao)程序(xu)?大場景(jing)?微信小(xiao)程序(xu)本質上來(lai)說就是一個 HTML 5(移(yi)動網頁) 應用(yong),用(yong)view、scoll-view代替了div標簽(qian)等,換湯不換藥。在微信中運行(xing)時,微信小(xiao)程序(xu)獲得更多的(de)系統(tong)權限(xian)。首先(xian)是數據緩存能力,這(zhe)可(ke)以讓用(yong)戶在打開 ...
微(wei)信(xin)(xin)小程序(xu)本質上(shang)(shang)來說(shuo)就(jiu)是一(yi)個 HTML 5(移動網頁) 應(ying)(ying)用(yong)(yong),用(yong)(yong)view、scoll-view代替了(le)div標簽等,換湯(tang)不(bu)換藥。在微(wei)信(xin)(xin)中運行時,微(wei)信(xin)(xin)小程序(xu)獲(huo)得更多的(de)系統(tong)權(quan)限。首(shou)先是數據緩(huan)存(cun)能(neng)力,這可以讓(rang)用(yong)(yong)戶在打開(kai)一(yi)個小程序(xu)的(de)時候將程序(xu)的(de)主要(yao)(yao)(yao)框架緩(huan)存(cun)到微(wei)信(xin)(xin)上(shang)(shang),下一(yi)次(ci)就(jiu)可以快速(su)打開(kai)了(le)。微(wei)信(xin)(xin)創始人張小龍曾說(shuo)過,微(wei)信(xin)(xin)應(ying)(ying)用(yong)(yong)號希望實現的(de)目(mu)標是“用(yong)(yong)完即走,無需安裝和卸載”,也就(jiu)是說(shuo)以后當你要(yao)(yao)(yao)使(shi)(shi)用(yong)(yong)一(yi)個應(ying)(ying)用(yong)(yong)時,只需要(yao)(yao)(yao)在微(wei)信(xin)(xin)里(li)搜索就(jiu)可以直接使(shi)(shi)用(yong)(yong)了(le),如摩(mo)拜(bai)、美(mei)團(tuan)等小型使(shi)(shi)用(yong)(yong)低頻的(de)app使(shi)(shi)用(yong)(yong)該套技(ji)術可大量節省開(kai)發成本。最近又(you)新增了(le)開(kai)放個人開(kai)發、公眾號關(guan)聯推送的(de)加強,可謂使(shi)(shi)用(yong)(yong)場景不(bu)容小覷。
由于本(ben)人吃貨(huo)一(yi)枚,家門口有(you)一(yi)家KFC,之前KFC的app經常有(you)一(yi)些(xie)福利卷,既(ji)然用慣了(le)這(zhe)個便捷(jie)實惠的app,于是就做(zuo)(zuo)它(ta)了(le)。 言歸正傳(chuan),先(xian)來分(fen)析(xi)一(yi)下一(yi)步一(yi)步該做(zuo)(zuo)啥,做(zuo)(zuo)一(yi)個小demo成就感還是滿(man)滿(man)的。

附近位置選擇-聯動(dong)菜單導航(hang)-模擬數(shu)據-抽屜式購物車-獲(huo)取用戶微信(xin)信(xin)息-頁面(mian)傳值-數(shu)據生(sheng)成訂單
//xurenjie.cn:3000/img/KFC/KFC_gif.gif
抱歉!!GIF太(tai)(tai)卡了太(tai)(tai)卡了,簡(jian)易clone下來本地跑起(qi)來效(xiao)果最(zui)佳(jia) 直接點餐會自動為你找到最(zui)近的(de)餐廳,不(bu)過離最(zui)近的(de)kfc太(tai)(tai)遠(yuan)的(de)不(bu)太(tai)(tai)行
├── app.js
├── app.json
├── app.wxss
├── pages
│ ├── .DS_Store
│ ├── KFC
│ │ ├── KFC.js
│ │ ├── KFC.wxml
│ │ └── KFC.wxss
│ ├── card
│ │ ├── card.js
│ │ ├── card.wxml
│ │ └── card.wxss
│ ├── halladdress
│ │ ├── .DS_Store
│ │ ├── halladdress.js
│ │ ├── halladdress.wxml
│ │ └── halladdress.wxss
│ ├── index
│ │ ├── index.js
│ │ ├── index.wxml
│ │ └── index.wxss
│ ├── logs
│ │ ├── logs.js
│ │ ├── logs.json
│ │ ├── logs.wxml
│ │ └── logs.wxss
│ ├── menu
│ │ ├── index.html
│ │ ├── menu.js
│ │ ├── menu.wxml
│ │ └── menu.wxss
│ ├── order
│ │ ├── order.js
│ │ ├── order.wxml
│ │ └── order.wxss
│ └── takeout
│ ├── message
│ │ ├── message.js
│ │ ├── message.wxml
│ │ └── message.wxss
│ ├── qqmap-wx-jssdk.min.js
│ ├── takeout.js
│ ├── takeout.wxml
│ └── takeout.wxss
├── style
│ ├── .DS_Store
│ └── weui.wxss
└── utils
└── util.js
pages: [
pages/index/index, // 首頁
pages/KFC/KFC, // K金商城頁
pages/menu/menu, // 菜單頁
pages/card/card, // 卡包頁
pages/order/order, // 訂單頁
pages/takeout/takeout, // 外賣地圖頁
pages/takeout/message/message, // 填寫外賣信息頁
pages/halladdress/halladdress, // 附近餐廳頁
pages/logs/logs // 日志頁
]
我(wo)們(men)可(ke)以通過官網的(de)文檔(dang)或(huo)W3C教程上初始化了一個(ge)小程序(xu)目(mu)錄,小程序(xu)的(de)每個(ge)頁(ye)面都放在(zai)pages目(mu)錄下(xia) 每次(ci)添加(jia)一個(ge)新頁(ye)面,都需要先在(zai)app.json.page下(xia)注(zhu)冊。
mock.js大紅大紫,讓前端(duan)獨立于后端(duan),用(yong)它來(lai)模擬KFC數(shu)據(ju) 不(bu)太清楚使(shi)用(yong)的同學可以(yi)參(can)考:
因為菜單(dan)中每個左側的(de)分類對應(ying)一組數據,在(zai)右(you)側也需(xu)要渲(xuan)染類名(ming),因此簡(jian)單(dan)模擬結構
[{ title: 這里放左邊列表的組名,
foodsIndex: [{
name: 這里放每個食物的名字,
price: 11.0,
url: //imgm.4008823823.com.cn/kfcmwos/img//S/269_116012.jpg
},
{},{},{}]
你(ni)可(ke)以嘗試自己去(qu)扒(ba)(ba)肯德基點餐,或者用我扒(ba)(ba)好的肯德基API

用(yong)toast優(you)化耗時加(jia)載
wx.showToast({
title: 地圖加載中,
icon: loading,
duration: 0,
mask: true
})
畫圖(tu)完成(cheng)后用回調將Toast去除
this.mapCtx = wx.createMapContext(myMap, function () {
wx.hideToast();
})
WXML:
<map id=myMap longitude={{longitude}} latitude={{latitude}}
style=width: 100%; height: 100% markers={{markers}} covers={{covers}} scale=18>
map>
以搜(sou)附近地點渲染至頁面列表(biao)為例
let QQMapWX = require(qqmap-wx-jssdk.min.js);
let demo = new QQMapWX({
key: 5Q2BZ-O3W24-V6DUN-DZ4Z7-H427K-WCB7R // 必填
});
demo.reverseGeocoder({
location: {
latitude: _latitude,
longitude: _longitude
},
get_poi: 1,
success: function (res) {
// console.log(res);
},
fail: function (res) {
console.log(res);
},
complete: function (res) {
console.log(res);
that.setData({
pois: res.result.pois
})
}
});
通過setData() 我們的數(shu)據就傳到data上去中(zhong)了便用(yong)此渲染頁面(mian)上去,that保持對原page對象的引用(yong)喲
<view class=address-item wx:for={{pois}} wx:for-item=poi
data-name={{poi.address}} catchtap=ToDetailPage>
<image src=../../image/position.png data-name={{poi.address}}
catchtap=ToDetailPage></image>
<text catchtap=ToDetailPage data-name={{poi.address}}>{{poi.address}}</text>
</view>
以搜周圍(wei)的KFC為例
demo.search({
keyword: 肯德(de)基,
location: {
latitude: _latitude,
longitude: _longitude
},
success: function (res) {
// console.log(res);
},
fail: function (res) {
// console.log(res);
},
complete: function (res) {
console.log(res.data[0].location.lat,res.data[0].location.lng)
console.log(res.data[0])
// .address._distance
that.setData({
poi: res.data[0].address,
distance: res.data[0]._distance,
latitude: res.data[0].location.lat,
longitude: res.data[0].location.lng,
markers: [{
latitude: res.data[0].location.lat,
longitude: res.data[0].location.lng,
name: KFC,
desc: KFC在您身邊
}]
})
}
});
換(huan)湯不換(huan)藥核心還(huan)是(shi)通過(guo)setData改變data從而讓頁面顯示當前kfc,沒有用(yong)輸入框搜索,用(yong)設置(zhi)的自動(dong)搜索
gif炸了的(de)話直接看下面部分的(de)圖吧,忽略底下的(de)購物車
左邊點(dian)擊菜單的不(bu)同種(zhong)類,右邊轉到(dao)相應的的內容 這里的實(shi)現,用(yong)到(dao)了scroll-view的API 給每個右邊的內容對象渲染時附(fu)上id
<view class=food-list wx:for={{foodArray}} wx:for-item=item id=foodtype{{index}}>
再給(gei)每(mei)個(ge)nav的點擊事件dataset解析一下
let goPage = e.currentTarget.id
this.setData({
scroll_into_view: foodtype + goPage
})

我在這里的(de)做法是給每個商品(pin)(pin)都賦(fu)了一個dataset,以便(bian)點擊(ji)不(bu)同(tong)的(de)商品(pin)(pin)讓不(bu)同(tong)的(de)對象(xiang)進入購(gou)物車數組,通過e.target.dataset拿到
// 是否有同種商品判斷
if (this.data.shoppingList.length > 0) {
// 商品名是否相同判斷,不重復添加同名商品
let isHave = this.data.shoppingList.findIndex(item => item.name == e.target.dataset.name)
if (isHave != -1) {
that.data.shoppingList[isHave].num++
} else {
// 購物車數組加進新的一樣食品
that.data.shoppingList.push({
price: e.target.dataset.price,
name: e.target.dataset.name,
num: itemNum
})
// 動畫效果的長度添加
move_length++
}
// 沒有商品時直接添加
} else {
this.data.shoppingList.push({
price: e.target.dataset.price,
name: e.target.dataset.name,
num: itemNum
})
move_length++
}
可參(can)照API 我在這里是做了一個增(zeng)加商品(pin)時,抽屜(ti)往上滾動,刪除為空時抽屜(ti)向下滾動
data: {
totalCount: 0, // 購物車的總數量
movelength: 0, // 上移或下拉動畫的單位距離
cartIsHidden: true, // 購物車是否隱藏
cartIndexIsHidden: true, // 購物車詳情菜單是否隱藏
animationData: {} // 動畫動作對象
}
滾動動畫(hua)初(chu)始設置
let animation = wx.createAnimation({
duration: 400,
timingFunction: linear,
delay: 0
});
動畫(hua)產(chan)生的(de)效果就以bottom的(de)變(bian)化(hua)而產(chan)生
let mlength = move_length * 55;
if (move_length > 1) {
mlength = 55 + (move_length - 1) * 65;
}
this.animation = animation
animation.bottom(mlength).step()
加(jia)入動畫序列,并設置好movelength
this.setData({
animationData: animation.export()
})
this.setData({
shoppingList: shopping_list,
totalPrice: total_price,
totalCount: total_count,
// 購物車當有商品時彈出
cartIsHidden: false,
movelength: move_length
})
}
參考大(da)佬掘金微信小程序(xu)多頁面(mian)傳參通信的探索與實踐(jian)

比(bi)如(ru)這個頁面(mian),它的(de)所有數據都來之于之前的(de)選擇 我在自己項目里目前用的(de)是(shi)本地存(cun)儲的(de)方式(shi),比(bi)如(ru)地址的(de)設(she)置獲取
在(zai)選擇頁(ye)設置本地存儲
let OrderAddress = {
address: [],
isHall: false
}
//遍歷去重
let item = OrderAddress.address.find(item=>item==event.target.dataset.name)
if(!item){
OrderAddress.address.push(event.target.dataset.name)
}
wx.setStorage({
key: OrderAddress,
data: OrderAddress,
});
wx.navigateTo({
url:/pages/takeout/message/message
})
在訂單頁拿到地址,對api不(bu)(bu)熟悉多console.log幾下,沒有什么解決不(bu)(bu)了的~
wx.getStorage({
key: OrderAddress,
success: function (res) {
console.log(res.data);
that.setData({
address: res.data.address[0],
elementToggle: res.data.isHall
})
}
})
因為還沒有上rpx:真機樣(yang)式(shi)有差距;同(tong)樣(yang)設置幾行文本,高度是不(bu)一致的。
騰訊地(di)圖的大坑z-index,本來用(yong)地(di)圖的api想做一個搜(sou)索自動提示,但繪(hui)制(zhi)的地(di)圖是微信內置的,z-index再高都根(gen)本無法(fa)覆蓋在地(di)圖上面(mian)(mian),解決辦(ban)法(fa)是另外跳入一個頁(ye)面(mian)(mian)處理
需要申請(qing)合法域(yu)名,請(qing)求里合法域(yu)名有個數限制。
頁面內(nei)跳轉不能超過5級。