微信小程序踩坑記

搭建環(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就是那么的簡單。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容