小程序?大場(chǎng)景?微信小程序本質(zhì)上來(lái)說(shuō)就是一個(gè) HTML 5(移動(dòng)網(wǎng)頁(yè)) 應(yīng)用,用view、scoll-view代替了div標(biāo)簽等,換湯不換藥。在微信中運(yùn)行時(shí),微信小程序獲得更多的系統(tǒng)權(quán)限。首先是數(shù)據(jù)緩存能力,這可以讓用戶在打開 ...
微信小程序本質(zhì)上來(lái)說(shuō)就是一個(gè) HTML 5(移動(dòng)網(wǎng)頁(yè)) 應(yīng)用,用view、scoll-view代替了div標(biāo)簽等,換湯不換藥。在微信中運(yùn)行時(shí),微信小程序獲得更多的系統(tǒng)權(quán)限。首先是數(shù)據(jù)緩存能力,這可以讓用戶在打開一個(gè)小程序的時(shí)候?qū)⒊绦虻闹饕蚣芫彺娴轿⑿派?,下一次就可以快速打開了。微信創(chuàng)始人張小龍?jiān)f(shuō)過(guò),微信應(yīng)用號(hào)希望實(shí)現(xiàn)的目標(biāo)是“用完即走,無(wú)需安裝和卸載”,也就是說(shuō)以后當(dāng)你要使用一個(gè)應(yīng)用時(shí),只需要在微信里搜索就可以直接使用了,如摩拜、美團(tuán)等小型使用低頻的app使用該套技術(shù)可大量節(jié)省開發(fā)成本。最近又新增了開放個(gè)人開發(fā)、公眾號(hào)關(guān)聯(lián)推送的加強(qiáng),可謂使用場(chǎng)景不容小覷。
由于本人吃貨一枚,家門口有一家KFC,之前KFC的app經(jīng)常有一些福利卷,既然用慣了這個(gè)便捷實(shí)惠的app,于是就做它了。 言歸正傳,先來(lái)分析一下一步一步該做啥,做一個(gè)小demo成就感還是滿滿的。
附近位置選擇-聯(lián)動(dòng)菜單導(dǎo)航-模擬數(shù)據(jù)-抽屜式購(gòu)物車-獲取用戶微信信息-頁(yè)面?zhèn)髦?數(shù)據(jù)生成訂單
http://xurenjie.cn:3000/img/KFC/KFC_gif.gif
抱歉!!GIF太卡了太卡了,簡(jiǎn)易clone下來(lái)本地跑起來(lái)效果最佳 直接點(diǎn)餐會(huì)自動(dòng)為你找到最近的餐廳,不過(guò)離最近的kfc太遠(yuǎn)的不太行
├── 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, // 首頁(yè)
pages/KFC/KFC, // K金商城頁(yè)
pages/menu/menu, // 菜單頁(yè)
pages/card/card, // 卡包頁(yè)
pages/order/order, // 訂單頁(yè)
pages/takeout/takeout, // 外賣地圖頁(yè)
pages/takeout/message/message, // 填寫外賣信息頁(yè)
pages/halladdress/halladdress, // 附近餐廳頁(yè)
pages/logs/logs // 日志頁(yè)
]
我們可以通過(guò)官網(wǎng)的文檔或W3C教程上初始化了一個(gè)小程序目錄,小程序的每個(gè)頁(yè)面都放在pages目錄下 每次添加一個(gè)新頁(yè)面,都需要先在app.json.page下注冊(cè)。
mock.js大紅大紫,讓前端獨(dú)立于后端,用它來(lái)模擬KFC數(shù)據(jù) 不太清楚使用的同學(xué)可以參考:
因?yàn)椴藛沃忻總€(gè)左側(cè)的分類對(duì)應(yīng)一組數(shù)據(jù),在右側(cè)也需要渲染類名,因此簡(jiǎn)單模擬結(jié)構(gòu)
[{ title: 這里放左邊列表的組名,
foodsIndex: [{
name: 這里放每個(gè)食物的名字,
price: 11.0,
url: http://imgm.4008823823.com.cn/kfcmwos/img//S/269_116012.jpg
},
{},{},{}]
你可以嘗試自己去扒肯德基點(diǎn)餐,或者用我扒好的肯德基API
用toast優(yōu)化耗時(shí)加載
wx.showToast({
title: 地圖加載中,
icon: loading,
duration: 0,
mask: true
})
畫圖完成后用回調(diào)將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>
以搜附近地點(diǎn)渲染至頁(yè)面列表為例
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
})
}
});
通過(guò)setData() 我們的數(shù)據(jù)就傳到data上去中了便用此渲染頁(yè)面上去,that保持對(duì)原page對(duì)象的引用喲
<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>
以搜周圍的KFC為例
demo.search({
keyword: 肯德基,
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在您身邊
}]
})
}
});
換湯不換藥核心還是通過(guò)setData改變data從而讓頁(yè)面顯示當(dāng)前kfc,沒(méi)有用輸入框搜索,用設(shè)置的自動(dòng)搜索
gif炸了的話直接看下面部分的圖吧,忽略底下的購(gòu)物車
左邊點(diǎn)擊菜單的不同種類,右邊轉(zhuǎn)到相應(yīng)的的內(nèi)容 這里的實(shí)現(xiàn),用到了scroll-view的API 給每個(gè)右邊的內(nèi)容對(duì)象渲染時(shí)附上id
<view class=food-list wx:for={{foodArray}} wx:for-item=item id=foodtype{{index}}>
再給每個(gè)nav的點(diǎn)擊事件dataset解析一下
let goPage = e.currentTarget.id
this.setData({
scroll_into_view: foodtype + goPage
})
我在這里的做法是給每個(gè)商品都賦了一個(gè)dataset,以便點(diǎn)擊不同的商品讓不同的對(duì)象進(jìn)入購(gòu)物車數(shù)組,通過(guò)e.target.dataset拿到
// 是否有同種商品判斷
if (this.data.shoppingList.length > 0) {
// 商品名是否相同判斷,不重復(fù)添加同名商品
let isHave = this.data.shoppingList.findIndex(item => item.name == e.target.dataset.name)
if (isHave != -1) {
that.data.shoppingList[isHave].num++
} else {
// 購(gòu)物車數(shù)組加進(jìn)新的一樣食品
that.data.shoppingList.push({
price: e.target.dataset.price,
name: e.target.dataset.name,
num: itemNum
})
// 動(dòng)畫效果的長(zhǎng)度添加
move_length++
}
// 沒(méi)有商品時(shí)直接添加
} else {
this.data.shoppingList.push({
price: e.target.dataset.price,
name: e.target.dataset.name,
num: itemNum
})
move_length++
}
可參照API 我在這里是做了一個(gè)增加商品時(shí),抽屜往上滾動(dòng),刪除為空時(shí)抽屜向下滾動(dòng)
data: {
totalCount: 0, // 購(gòu)物車的總數(shù)量
movelength: 0, // 上移或下拉動(dòng)畫的單位距離
cartIsHidden: true, // 購(gòu)物車是否隱藏
cartIndexIsHidden: true, // 購(gòu)物車詳情菜單是否隱藏
animationData: {} // 動(dòng)畫動(dòng)作對(duì)象
}
滾動(dòng)動(dòng)畫初始設(shè)置
let animation = wx.createAnimation({
duration: 400,
timingFunction: linear,
delay: 0
});
動(dòng)畫產(chǎn)生的效果就以bottom的變化而產(chǎn)生
let mlength = move_length * 55;
if (move_length > 1) {
mlength = 55 + (move_length - 1) * 65;
}
this.animation = animation
animation.bottom(mlength).step()
加入動(dòng)畫序列,并設(shè)置好movelength
this.setData({
animationData: animation.export()
})
this.setData({
shoppingList: shopping_list,
totalPrice: total_price,
totalCount: total_count,
// 購(gòu)物車當(dāng)有商品時(shí)彈出
cartIsHidden: false,
movelength: move_length
})
}
參考大佬掘金微信小程序多頁(yè)面?zhèn)鲄⑼ㄐ诺奶剿髋c實(shí)踐
比如這個(gè)頁(yè)面,它的所有數(shù)據(jù)都來(lái)之于之前的選擇 我在自己項(xiàng)目里目前用的是本地存儲(chǔ)的方式,比如地址的設(shè)置獲取
在選擇頁(yè)設(shè)置本地存儲(chǔ)
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
})
在訂單頁(yè)拿到地址,對(duì)api不熟悉多console.log幾下,沒(méi)有什么解決不了的~
wx.getStorage({
key: OrderAddress,
success: function (res) {
console.log(res.data);
that.setData({
address: res.data.address[0],
elementToggle: res.data.isHall
})
}
})
因?yàn)檫€沒(méi)有上rpx:真機(jī)樣式有差距;同樣設(shè)置幾行文本,高度是不一致的。
騰訊地圖的大坑z-index,本來(lái)用地圖的api想做一個(gè)搜索自動(dòng)提示,但繪制的地圖是微信內(nèi)置的,z-index再高都根本無(wú)法覆蓋在地圖上面,解決辦法是另外跳入一個(gè)頁(yè)面處理
需要申請(qǐng)合法域名,請(qǐng)求里合法域名有個(gè)數(shù)限制。
頁(yè)面內(nèi)跳轉(zhuǎn)不能超過(guò)5級(jí)。