美文网首页
微信小程序踩坑记

微信小程序踩坑记

作者: 等酒香醇V | 来源:发表于2017-10-22 10:01 被阅读0次

    搭建环境

    按照官方的简易教程搭建。微信小程序简易上手

    网上查找开源项目

    在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就是那么的简单。

    相关文章

      网友评论

          本文标题:微信小程序踩坑记

          本文链接:https://www.haomeiwen.com/subject/yblguxtx.html