小程序开发总结

微信小程序


近期在开发一个新的小程序,应该也是我在这家公司负责的最后一个项目了,主要做了购物车 提交订单 支付 商品详情页 首页 促销广告页等

记录一些开发总结
首先wx.request需要封装,登录也需要封装
其次从架构角度考虑,通用模块和功能需要抽出
比如地址列表地址组件在会员中心和提交订单页用得到,需要抽成组件
在这里插入图片描述

购物车和商品详情页都用到的选择地址组件,需要抽成组件
在这里插入图片描述
还有首页 促销广告页 订单页都用到的加车,那么加车需要写一个公共加车js
以及提交订单页和订单二次支付都用的到支付,需要写一个支付js
在这里插入图片描述


封装wx.request

用promise封装wx.request

return new Promise((resolve, reject) => {
  wx.request({
    url: OPTIOIN.url,
    method: OPTIOIN.method,
    dataType: "json",
    header: {
      ...OPTIOIN.header,
      Cookie: loginCookies,
      "Content-Type": OPTIOIN.contentType,
    },
    data: OPTIOIN.params,
    success: async function ({ data, errMsg, statusCode, header = {} }) {
     	if (statusCode == 200) {
        resolve(data);
      } else {
        reject(errMsg);
      }
    },
    fail: function (res) {
      wx.showToast({
        title: "网络异常,请稍后重试哦!",
        icon: "none",
      });
      reject(res);
    },
  });
});

封装request根据项目需要,再判断header是否需要缓存,是否需要设置cookie,还有其他http报错码处理,比如500,302等等都可以在这里处理

设置安全区域

适配iphonex及以上机型

padding-bottom: calc(100rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(100rpx + env(safe-area-inset-bottom));

ios11新增属性,constant兼容 IOS<11.2,env兼容 IOS>11.2

小程序中使用less

使用less方便一些

在xx.wxss同级目录下新建xx.less文件,vscode中安装插件Easy LESS,保存的时候会自动编译wxss文件

导航栏

导航栏支持点击跳转到对应区域,支持滚动到对应区域跟随改变

在这里插入图片描述

<!-- 导航栏 -->
<view class="nav-content" style="background:rgba(255,255,255,{{tabOpacity}});padding-top: {{navTop}}px;">
  <view class="tab-bar" style="opacity:{{tabOpacity}}">
    <view class="tab-item {{selectIndex == item.num ? 'tab-select' : ''}} {{index==0?'tab-item-first':''}}"
      wx:for="{{tabBarList}}" wx:key="index" bindtap="jumpTo" data-num="{{item.num}}" data-area="{{item.area}}">
      {{item.title}}
      <view class="tab-line"></view>
    </view>
  </view>
</view>
  //页面渲染完成后,要记录图文详情和包装售后的位置
  //记录图文详情、包装售后的top值
  calTop(){
    const { tabBarList } = this.data;
    tabBarList.forEach((item)=>{
      const query = this.createSelectorQuery();
      query.select('#'+item.area).boundingClientRect();
      query.exec(function (res) {
        if (res[0] && res[0].top) {
          item.top = res[0].top;
        }
      });
    })
    this.setData({tabBarList})
  },
  // 页面滚动,判断大于150后,显示导航栏,同时判断滚动距离到对应区域改变选中下标
  // 页面滚动事件 onPageScroll增加防抖
  // onPageScroll: debounce(function (event) {
  onPageScroll (event) {
    const { scrollTop } = event;
    if (scrollTop > 150) {
      this.setData({ tabOpacity: 1, scrollTop })
    } else {
      this.setData({ tabOpacity: 0, scrollTop })
    }
    //反推tabbar下标
    let { tabBarList, selectIndex } = this.data;
    let _scrollTop = scrollTop+400;
    if(_scrollTop>tabBarList[1].top){
      selectIndex = 2 //选中包装售后
    }else{
      selectIndex = 1 //选中图文详情
    }
    this.setData({selectIndex})
  },
  // }, 200),
  // 点击tab栏跳转
  jumpTo(e) {
    let { num } = e.currentTarget.dataset
    const { tabBarList } = this.data;
    this.setData({
      selectIndex: num
    })
    wx.pageScrollTo({
      scrollTop: tabBarList[num-1].top-110
    })
  },
onReachBottom

小程序拥有页面上拉触底事件的处理函数onReachBottom

当上拉至底部时就会触发onReachBottom函数来进行相应动作。也就是说小程序自带能捕捉到用户触底事件的函数。我们无需再进行捕捉用户事件了

组件内执行onPageScroll或者onReachBottom

onPageScroll onReachBottom都是page内的方法,组件内怎么使用呢

//page
onPageScroll (e) {
    this.selectComponent("#floor-water") && this.selectComponent("#floor-water").pageScroll(e);
  },
  onReachBottom (e) {
    this.selectComponent("#floor-water") && this.selectComponent("#floor-water").reachBottom(e);
  },
//component
pageScroll (e) {
  //处理逻辑
},
reachBottom (e) {
  //处理逻辑
},

选择组件调用组件内的方法

scrollView

实现点击切换,到边缘区域自动滚动漏出下一个

在这里插入图片描述
当点击到超春季新品时,漏出下一个,让用户知道后面还有类目,向前点击也是同理
在这里插入图片描述

//初始化的时候设置好id
lifetimes: {
  attached: function () {
    let navList = this.data.floorData;
    navList.forEach((item,index)=>{
      item.id = 'id'+index
    })
    this.setData({
      navList,
    });
  }
},
<scroll-view wx:else class="goods-nav goods-nav-static" scroll-x="true" scroll-into-view="{{activeNavId}}">
  <view id="{{item.id}}" class="goods-nav-item {{index == activeNavIdx ? 'on' : ''}}" wx:for="{{navList}}" wx:key="index" bindtap="checkNav" data-item="{{item}}" data-idx="{{index}}">{{item.name}}</view>
</scroll-view>

scroll-into-view属性

// 切换大类
checkNav (e) {
  const {item, idx} = e.currentTarget.dataset;
  const { activeNavId, activeNavIdx, navList } = this.data;
  let _activeNavId = activeNavId;
  //判断点击第一个和最后一个标签的情况,其余情况,聚焦到当前点击的前一个,保证前后都有露出
  if(idx+1 == navList.length){
    _activeNavId = navList[navList.length-1].id
  }else if(idx == 0){
    _activeNavId = 'id0'
  }else if(idx>activeNavIdx || idx<activeNavIdx){
    _activeNavId = navList[idx-1].id
  }
  this.setData({
    activeNavIdx: idx,
    activeNavId: _activeNavId,
  });
},
小程序支付

如果小程序内需要支付功能,那封装一个支付js就很有必要

import API from '../api/index';

const wxPay = function (param) {
  return new Promise((resolve, reject) => {
  	//调取服务端拿到支付参数
    API.pay.payOrder(param).then((payOrder)=>{
      let payForm = JSON.parse(payOrder.resStr)
      wx.requestPayment({
        timeStamp: payForm.timeStamp || '',
        nonceStr: payForm.nonceStr || '',
        package: payForm.package || '',
        signType: 'MD5',
        paySign: payForm.paySign || '',
        success (res) {
          if (res.errMsg === 'requestPayment:ok') {
            wx.showToast({
              icon: 'none',
              title: '支付成功',
            })
          }
          resolve(payOrder)
        },
        fail (res) {
          wx.showToast({
            icon: 'none',
            title: '支付失败',
          })
          reject(payOrder)
        }
      });
    }).catch((e)=>{
      console.log(e)
      wx.showToast({
        icon: 'none',
        title: '支付下单失败,请稍后再试',
      })
    })
  })
}

module.exports = {
  wxPay,
}

利用map去重

有的促销信息,同一种促销优惠返回了多种,只取同类的第一个,去重

//去重
let map = new Map()
promotion.activityList = promotion.activityList.filter((item) => {
  return !map.has(item.activityType) && map.set(item.activityType, 1)
})
拆分数组

有的接口一次只支持查询20个数据

//查询促销信息 一次最多查20个
let productsList = ['假设它长度为100'];
let productsListAll = [];
//按20 20拆分
if(productsList.length){
  for(var i=0,len=productsList.length;i<len;i+=20){
    productsListAll.push(productsList.slice(i,i+20));
  }
}
//循环调用
productsListAll.forEach(async (item)=>{
  let params = {
    productsList: item,
  }
  const promotions = await API.goods.promotionsTags(params);
  if(promotions){
    //处理数据
  }
  console.log(goodsList)
  this.setData({goodsList})
})

未完待续,持续补充…

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值