搭建环境
按照官方的简易教程搭建。微信小程序简易上手
网上查找开源项目
在github上面查找开源项目,以供上手。准备开发一个电商小程序,因此找了wechat-weapp-mall。
因为是个人练手项目,没有素材,直接使用了该项目的素材,然后模仿开发。
页面设计
- 首页
- 分类
- 购物车、订单
- 个人信息
- 其他各种功能尝试,暂时没头绪,后续添加。
使用小程序默认项目,对面模块建立对应的目录
- index
- classify
- order
- userinfo
在app.json的pages中引入对应的模块。
开发首页
首页功能列表
- 扫一扫、搜索框、交流信息
- 轮播
- 分栏商品
- 底部(共有导航模块)
扫一扫、搜索框、交流信息。
事件绑定使用bindtap,扫码使用接口scanCode,扫码API
注意:本地图片资源不能使用,因此要使用网络图片资源。
<image class="sort-icon" src='/images/扫一扫.png' bindtap="saoyisao"></image>
saoyisao: function () {
//扫码
wx.scanCode({
success: (res) => {
console.log(res)
}
});
}
搜索框实现,样式搞了好久。联想输入框有待实现。
- 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来进行数据绑定。class里面的插值表达式来进行样式的变动。
<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
})
}
交流信息,即客服等等有待实现。
轮播+路由跳转开发
使用swiper标签进行开发,记得设置元素的高宽度。
- 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绑定点击事件,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);
}
底部导航
在app.json中添加如下代码即可,如果内容页的导航地址有跟底部导航一样的跳不过去。
"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在数组会变的情况下,尽量使用wx:key。微信支付功能由于条件不具备,因此只是使用了模态框模拟。
- 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是每次显示页面的时候都会调用次方法。
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
//页面数据初始化
hasProduct: false,
productList: []
},
onLoad: function (options) {
//监听页面加载,页面初始化,options为页面跳转所带来的参数
// 检查是否登录
wx.checkSession({
success: function () {
console.log("已经登录");
},
fail: function () {
//登录态过期
app.globalData.login();
}
});
},
onReady: function () {
//监听页面渲染完成
},
onShow: function () {
//监听页面显示
// this.data.productList = app.globalData.carList;
if (app.globalData.carList.length > 0) {
this.setData({
productList: app.globalData.carList,
hasProduct: true
});
}
},
onHide: function () {
//监听页面隐藏
},
onUnload: function () {
//监听页面卸载
},
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需要逗号分开。多选框位置偏下,不知道如何调,以后想方法。
.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;
}
因为没有后台,其他页面不进行模拟了,下面学习小程序的地图等功能。
地图使用。
实现了获取当前位置,订单轨迹、打电话功能
- 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
//获取应用实例
const app = getApp()
Page({
data: {
latitude: 0,
longitude: 0,
markers: [],
polyline: [],
controls: []
},
onLoad: function (options) {
//监听页面加载,页面初始化,options为页面跳转所带来的参数
},
onReady: function () {
//监听页面渲染完成
},
onShow: function () {
//监听页面显示
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 () {
//监听页面隐藏
},
onUnload: function () {
//监听页面卸载
},
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
})
}
})
小结
基本上掌握了小程序的开发流程,个人感觉小程序的核心是如何设计漂亮的UI,剩余的都是调用小程序原有的接口便能满足。如果是前端工程师转入小程序就是零难度。
站在巨人的肩膀上,一个APP就是那么的简单。