搭建環(huán)境
按照官方的簡易教程搭建。微信小程序簡易上手
網(wǎng)上查找開源項(xiàng)目
在github上面查找開源項(xiàng)目,以供上手。準(zhǔn)備開發(fā)一個電商小程序,因此找了wechat-weapp-mall。
因?yàn)槭莻€人練手項(xiàng)目,沒有素材,直接使用了該項(xiàng)目的素材,然后模仿開發(fā)。
頁面設(shè)計
- 首頁
- 分類
- 購物車、訂單
- 個人信息
- 其他各種功能嘗試,暫時沒頭緒,后續(xù)添加。
使用小程序默認(rèn)項(xiàng)目,對面模塊建立對應(yīng)的目錄
- index
- classify
- order
- userinfo
在app.json的pages中引入對應(yīng)的模塊。
開發(fā)首頁
首頁功能列表
- 掃一掃、搜索框、交流信息
- 輪播
- 分欄商品
- 底部(共有導(dǎo)航模塊)
掃一掃、搜索框、交流信息。
事件綁定使用bindtap,掃碼使用接口scanCode,掃碼API
注意:本地圖片資源不能使用,因此要使用網(wǎng)絡(luò)圖片資源。
<image class="sort-icon" src='/images/掃一掃.png' bindtap="saoyisao"></image>
saoyisao: function () {
//掃碼
wx.scanCode({
success: (res) => {
console.log(res)
}
});
}
搜索框?qū)崿F(xiàn),樣式搞了好久。聯(lián)想輸入框有待實(shí)現(xiàn)。
- wxss
.sort-input {
width: 75%;
border: 1rpx solid #ddd;
border-radius: 5rpx;
}
.sort-input-bg {
/* background:bg-color bg-image position/bg-size bg-repeat bg-origin bg-clip bg-attachment initial|inherit; */
background: url("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1507043922110&di=2f65bebf9975e79f0642058c4dbb2bfb&imgtype=0&src=http%3A%2F%2F58pic.ooopic.com%2F58pic%2F14%2F64%2F63%2F96u58PICfAj.jpg");
background-size: 40rpx 40rpx;
background-repeat: no-repeat;
background-position: 5rpx;
}
.input-word {
font-size: 32rpx;
color: gainsboro;
padding-left: 60rpx;
}
- wxml,通過bindinput來進(jìn)行數(shù)據(jù)綁定。class里面的插值表達(dá)式來進(jìn)行樣式的變動。
<input class="sort-input {{inputValue == '' ? 'sort-input-bg':''}}" type="text" bindinput="bindKeyInput" placeholder="IPhone 8" placeholder-class="input-word"> </input>
<!-- <view class="section__title">你輸入的是:{{inputValue}}</view> -->
- js,鍵盤輸入事件。
bindKeyInput: function(e) {
this.setData({
inputValue: e.detail.value
})
}
交流信息,即客服等等有待實(shí)現(xiàn)。
輪播+路由跳轉(zhuǎn)開發(fā)
使用swiper標(biāo)簽進(jìn)行開發(fā),記得設(shè)置元素的高寬度。
- index.wxml
<swiper class="index-swiper" indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">
<block wx:for="{{imgUrls}}">
<swiper-item>
<navigator url='{{item.path}}' >
<image src="{{item.img}}" class="index-swiper" width="355" height="150" />
</navigator>
</swiper-item>
</block>
</swiper>
- index.js
data: {
imgUrls: [
{ path:'/pages/classify/classify',img:'http://img02.tooopen.com/images/20150928/tooopen_sy_143912755726.jpg'},
{ path: '/pages/classify/classify',img:'http://img06.tooopen.com/images/20160818/tooopen_sy_175866434296.jpg'},
{ path: '/pages/classify/classify',img:'http://img06.tooopen.com/images/20160818/tooopen_sy_175833047715.jpg'}
],
indicatorDots: true,
autoplay: true,
interval: 2000,
duration: 1000
},
- index.wxss
.index-swiper {
height: 400rpx;
width: 100%;
}
豎型輪播
<view class="hot">
<view class="hot-title">
<icon type="success" size="40" />
</view>
<view class="hot-content">
<swiper class="hot-swiper" vertical="true" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}">
<block wx:for="{{hot_data}}">
<swiper-item>
<navigator url='{{item.path}}'>
<text class="h-title">{{item.title}}</text>
<text class="h-content">{{item.content}}</text>
</navigator>
</swiper-item>
</block>
</swiper>
</view>
</view>
加入購物車
- wxml,使用bindtap綁定點(diǎn)擊事件,data-p傳值
<image class="add-to-car" src='/images/buy.png' bindtap="addToCar" data-p="{{item}}"></image>
- js,這里傳遞的是一個事件,事件里面的target.dataset便是我們傳遞的值,此處使用了app.js里面的全局變量來存值。
addToCar: function(event) {
getApp().globalData.carList.push(event.target.dataset.p);
}
底部導(dǎo)航
在app.json中添加如下代碼即可,如果內(nèi)容頁的導(dǎo)航地址有跟底部導(dǎo)航一樣的跳不過去。
"tabBar": {
"color": "#6e6d6b",
"selectedColor": "#f9f027",
"borderStyle": "white",
"backgroundColor": "#292929",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "images/footer-icon-01.png",
"selectedIconPath": "images/footer-icon-01-active.png",
"text": "極速免稅"
}, {
"pagePath": "pages/classify/index",
"iconPath": "images/footer-icon-02.png",
"selectedIconPath": "images/footer-icon-02-active.png",
"text": "分類"
}, {
"pagePath": "pages/cart/index",
"iconPath": "images/footer-icon-03.png",
"selectedIconPath": "images/footer-icon-03-active.png",
"text": "購物車"
}, {
"pagePath": "pages/my/index",
"iconPath": "images/footer-icon-04.png",
"selectedIconPath": "images/footer-icon-04-active.png",
"text": "我的"
}]
}
購物車、支付
模擬購物車
使用checkbox,wx:for在數(shù)組會變的情況下,盡量使用wx:key。微信支付功能由于條件不具備,因此只是使用了模態(tài)框模擬。
- wxml
<view class="container">
<view class="list" wx:if="{{hasProduct}}">
<view class="car-product">
<checkbox-group class="car-checkbox" bindchange="choice">
<lable class="car-label" wx:for="{{productList}}" wx:key="item.id">
<view class="p-img">
<checkbox class="pp-check" value="{{item.id}}" checked="{{item.checked}}" />
<image class="pp-img" src="{{item.img}}"></image>
</view>
<view class="p-detail">
<view class="p-name">
{{item.name}}
</view>
<view class="p-price">
¥{{item.price}} x {{item.count}}
</view>
</view>
</lable>
</checkbox-group>
</view>
<button class="buy" bindtap="buy">支付</button>
</view>
<view class="empty" wx:else="{{hasProduct}}">
<image src="/images/cart-null.png" class="car-null"></image>
<view class="car-null">購物車空空如也</view>
</view>
</view>
- js, onShow是每次顯示頁面的時候都會調(diào)用次方法。
//index.js
//獲取應(yīng)用實(shí)例
const app = getApp()
Page({
data: {
//頁面數(shù)據(jù)初始化
hasProduct: false,
productList: []
},
onLoad: function (options) {
//監(jiān)聽頁面加載,頁面初始化,options為頁面跳轉(zhuǎn)所帶來的參數(shù)
// 檢查是否登錄
wx.checkSession({
success: function () {
console.log("已經(jīng)登錄");
},
fail: function () {
//登錄態(tài)過期
app.globalData.login();
}
});
},
onReady: function () {
//監(jiān)聽頁面渲染完成
},
onShow: function () {
//監(jiān)聽頁面顯示
// this.data.productList = app.globalData.carList;
if (app.globalData.carList.length > 0) {
this.setData({
productList: app.globalData.carList,
hasProduct: true
});
}
},
onHide: function () {
//監(jiān)聽頁面隱藏
},
onUnload: function () {
//監(jiān)聽頁面卸載
},
choice: function (event) {
wx.setStorageSync('buyIds', event.detail.value);
},
buy: function () {
console.log(wx.getStorageSync('buyIds'));
wx.showModal({
title: '支付提示',
content: '總金額:¥100000000000',
confirmText: '支付',
success: function (res) {
if (res.confirm) {
wx.requestPayment({
'timeStamp': '',
'nonceStr': '',
'package': '',
'signType': 'MD5',
'paySign': '',
'success': function (res) {
wx.navigateTo({
url: '/pages/order/order'
});
},
'fail': function (res) {
console.log(res);
wx.navigateTo({
url: '/pages/order/order'
});
}
})
wx.showModal({content: '模擬支付'});
} else if (res.cancel) {
console.log('取消支付')
}
}
});
}
});
- wxss,多個class需要逗號分開。多選框位置偏下,不知道如何調(diào),以后想方法。
.container, .list, .car-product{
width: 100%;
}
.car-null{
width: 500rpx;
height: 500rpx;
align-items: center;
}
.car-label {
width: 100%;
height: 150rpx;
}
.p-img{
width: 45%;
height: 150rpx;
display: inline-block;
}
.pp-check {
width: 20%;
display: inline-block;
padding-left: 10rpx;
}
.pp-img{
width: 60%;
height: 150rpx;
padding-left: 10rpx;
padding-right: 10rpx;
display: inline-block;
}
.p-detail{
width: 50%;
height: 150rpx;
display: inline-block;
padding-left: 10rpx;
}
.p-name {
width: 100%;
height: 75rpx;
}
.p-price {
width: 100%;
height: 75rpx;
}
.buy {
/* position: fixed; */
/* right: 0rpx;
bottom: 0rpx; */
position:absolute;
right:0px;
bottom:0px;
border:1px solid #aaa;
}
因?yàn)闆]有后臺,其他頁面不進(jìn)行模擬了,下面學(xué)習(xí)小程序的地圖等功能。
地圖使用。
實(shí)現(xiàn)了獲取當(dāng)前位置,訂單軌跡、打電話功能
- wxml
<view class="container">
<map id="map" longitude="{{longitude}}" latitude="{{latitude}}" scale="14"
controls="{{controls}}"
markers="{{markers}}"
polyline="{{polyline}}"
show-location style="width: 100%; height: 300px;">
</map>
<button bindtap="showLine">顯示訂單軌跡</button>
<button bindtap="telphone" data-phone="15920971897">打電話給快遞員</button>
</view>
- js
//index.js
//獲取應(yīng)用實(shí)例
const app = getApp()
Page({
data: {
latitude: 0,
longitude: 0,
markers: [],
polyline: [],
controls: []
},
onLoad: function (options) {
//監(jiān)聽頁面加載,頁面初始化,options為頁面跳轉(zhuǎn)所帶來的參數(shù)
},
onReady: function () {
//監(jiān)聽頁面渲染完成
},
onShow: function () {
//監(jiān)聽頁面顯示
const _this = this;
wx.getLocation({
type: 'wgs84',
success: function (res) {
_this.setData({
latitude: res.latitude,
longitude: res.longitude,
markers: [{
iconPath: "/images/location.png",
id: 0,
latitude: res.latitude,
longitude: res.longitude,
width: 50,
height: 50
}]
});
}
})
},
onHide: function () {
//監(jiān)聽頁面隱藏
},
onUnload: function () {
//監(jiān)聽頁面卸載
},
showLine: function () {
let points = []
points.push({ longitude: this.data.longitude, latitude: this.data.latitude });
for (var index = 0; index < 10; index++) {
let lg = this.data.longitude + Math.random() * 0.1;
let lt = this.data.latitude + Math.random() * 0.1;
points.push({ longitude: lg, latitude: lt });
}
this.setData({
polyline: [{
points: points,
color: "#FF0000DD",
width: 2,
dottedLine: true
}]
});
},
telphone: function (event) {
wx.makePhoneCall({
phoneNumber: event.target.dataset.phone
})
}
})
小結(jié)
基本上掌握了小程序的開發(fā)流程,個人感覺小程序的核心是如何設(shè)計漂亮的UI,剩余的都是調(diào)用小程序原有的接口便能滿足。如果是前端工程師轉(zhuǎn)入小程序就是零難度。
站在巨人的肩膀上,一個APP就是那么的簡單。