github地址(欢迎star):https://github.com/xiaobinwu/dj

版本:0.15.152900(暂未升级原因:升级后需要图片无法本地引用,必须使用image或是远程路径引用)

目录结构

  • css => 放置公用wxss,目前只有一个font.wcss

  • image => 静态资源目录

  • lib => 第三方库(如:qqmap-wx-jssdk.min.js)

  • pages => 小程序页面(包括四个文件,.wxml/.wxss/.js/.json)

  • template => 抽离出来的template,具有复用性

  • utils => 工具类

  • app.js/app.json/app.wxss => 配置

踩过的坑

1. promise封装

官方request代码:

  1. wx.request({
  2. url: 'test.php', //仅为示例,并非真实的接口地址
  3. data: {
  4. x: '' ,
  5. y: ''
  6. },
  7. header: {
  8. 'content-type': 'application/json'
  9. },
  10. success: function(res) {
  11. console.log(res.data)
  12. }
  13. })

  

但是有很多场景需要promise化的,所以使用第三方promise库(es6-promise.min.js),对request进行了一层包装:

  1. /* utils/util.js */
  2. /* api接口promise 柯里化*/
  3. var Promise = require('../lib/es6-promise.min.js');
  4. function wxPromisify(fn, scope) {
  5. return function (obj = {}) {
  6. return new Promise((resolve, reject) => {
  7. obj.success = function (res) {
  8. resolve(res);
  9. }
  10. obj.fail = function (res) {
  11. reject(res);
  12. }
  13. if(scope){
  14. //改变this指向
  15. var newFn = fn.bind(scope);
  16. newFn(obj);
  17. }else{
  18. fn(obj);
  19. }
  20. })
  21. }
  22. }
  23. /* request 封装*/
  24. var wxrequest = wxPromisify(wx.request);
  25. function wxRequest(options, tokenNotRequired){
  26. return wxrequest(options).then(res => {
  27. var data = res.data;
  28. if(data.status === 404404) {
  29. if(tokenNotRequired){
  30. delete options.headers;
  31. return wxRequest(options);
  32. }else{
  33. return updateToken().then(token => {
  34. return wxRequest(object.assignIn(options, {
  35. headers: { 'X-Auth-Token': token }
  36. }));
  37. });
  38. }
  39. }else {
  40. return Promise.resolve(data);
  41. }
  42. }).catch(err => {
  43. return Promise.reject(err);
  44. });
  45. }

  

2. Javascript作用域问题

由于小程序默认给的微信地图api有些需求达不到要求,于是使用第三方库(qqmap-wx-jssdk.min.js,这是绝配),这样定位功能也比较好做,以及后续要做的地址管理模块也比较好下手,但是有个问题,对微信地图jdk接口进行promise化后,使用过程会报错,导致定位失败,所以需要改变其执行作用,于是对wxPromisify()方法做了些改造,重新绑定作用域至qqmapsdk,调用如下:

  1. //address.js
  2. // 引入SDK核心类
  3. var QQMapWX = require('../lib/qqmap-wx-jssdk.min.js');
  4. // 实例化API核心类(需要配置安全域名https://apis.map.qq.com)
  5. var qqmapsdk = new QQMapWX({
  6. key: 'xxxxx' //需要到腾地图上申请key
  7. });
  8.  
  9. ...
  10. ...
  11.  
  12. // 请求用户授权定位
  13. //逆地址解析
  14. var ReverseGeocoder = util.wxPromisify(qqmapsdk.reverseGeocoder, qqmapsdk); //需改变作用域

对于小程序是需要配置对应的安全域名的,这样才能执行request

3. 如何衍生出组件模板

模板页(template)没有天生配对js,但是也可以实现,实现面向对象的思想,对模板所需要的js进行一层类的封装,保证构造函数需要接受父页面的上下文对象,然后可以把声明好的类方法绑定到父页面上面去,对于模板页js方法,以_FUN()方式命名。下面是为图片懒加载优化而做的swiper模板组件,可以参考一下。

  1. /**
  2. * 图片预加载组件
  3. *
  4. * @author xiaobin_wu
  5. * template/silder/silder.js
  6. */
  7. class Slider {
  8. constructor(pageContext, options = { picList: [], showArr:[] }){
  9. this.page = pageContext; //获取页面上下文
  10. this.page.data.slider = {
  11. picList: options.picList,
  12. showArr: options.showArr
  13. }; //初始化data
  14. this.page._sliderChange = this._sliderChange.bind(this);
  15. }
  16. //监听滑动事件,实现图片懒加载
  17. _sliderChange(e){
  18. if(this.page.data.slider.showArr){
  19. let showArr = this.page.data.slider.showArr;
  20. for(let i = 0; i < showArr.length; i++){
  21. if(i === e.detail.current){
  22. showArr[i] = true;
  23. }
  24. }
  25. this.page.setData({
  26. 'slider.showArr': showArr
  27. });
  28. }
  29. }
  30. initData(imgs){
  31. const arr = new Array(imgs.length).fill(false);
  32. this.page.setData({
  33. 'slider.picList': imgs,
  34. 'slider.showArr': arr.fill(true, 0 , 1)
  35. });
  36. }
  37. }
  38. module.exports = Slider

以类形式module.exports出去,Page页面,以var Slider = require('../../template/slider/slider.js');形式引入,然后new操作,模板wxml也参考template/silder/silder.wxml,也可以对应写wxss,这样做模板页复用性高,类似组件的模式。

4. scroll-view使用scroll-x失效问题

刚开始使用scroll-view,scroll-x一直失效,不能水平scroll,折腾了好多时间,结果这样就成了,大概如下结构(home.wxml):

  1. <scroll-view scroll-x="{{true}}" scroll-left="{{scrollLeft}}" class="scroll-bar" style="width:100%;" >
  2. <view style="width: {{idxData.navbar.length * 168}}rpx">
  3. <view wx:for="{{idxData.navbar}}" wx:for-item="cate" class="cate-item {{index == currentIndex ? 'active' : ''}}" data-id="{{cate.nav_id}}" data-index="{{index}}" bindtap="cateClick">{{cate.nav_name}}</view>
  4. </view>
  5. </scroll-view>

忽略其他乱起八糟的代码,主要是这个<view style="width: {{idxData.navbar.length * 168}}rpx">,需要保证scroll-view下面的view的width必须要大于100%,充满整个scroll-view

4. swiper高度无法自动撑开,暂时不支持


于是对于红线部分的产品分类swiper,就只能手动计算swiper高度,来实现swiper的效果,但是由于对应每个swiper-item还会有个下拉加载,所以产品数目会一直变化,所以计算起来相当于耗性能,希望官方能尽快让swiper高度允许自动撑开

5. template模板

template模板,对象传递方式=>data={{a: x1,b: x2}},x1、x2对应data绑定的变量

6. setData设置动态数据

可能你会遇到这种情况(设置动态数据):

  1. this.setData({
  2. 'array[0]': 1
  3. });
  4. /*
  5. 上面这样设置是没问题的,但是是动态的,那该怎么办?这样...
  6.  
  7. */
  8. this.setData({
  9. 'array['+ index +']': 1
  10. });
  11. /*
  12. 很遗憾,无法怎么做
  13.  
  14. */

解决办法,声明中间量,如下:

  1. /* utils/util.js */
  2. //动态setData
  3. function dynamicSetData(field, index, value, suffix, type='object'){
  4. var param = {};
  5. var string = field + '[' + index + ']' + (typeof suffix !== 'undefined' ? type === 'object' ? '.' + suffix : '[' + suffix + ']' : '');
  6. param[string] = value;
  7. return param;
  8. }

这样最后就可以这样,this.setData(util.dynamicSetData('firstLoadDataFlag', index, true));,即可用于对象的改变,也可以用于数组的改变。

7. 设置顶层标签Page的样式,处理安卓机的背景色问题

8 px与rpx之间转化

对于小程序中,也有一些组件需要传递变量单位为px的,如果这个变量是需要计算出来的,但是我们使用的确是rpx单位,那么他们之间的转化比例是有必要知道的

  1. /* utils/util.js */
  2. //获取px与rpx之间的比列
  3. function getRpx(){
  4. var winWidth = wx.getSystemInfoSync().windowWidth;
  5. return 750/winWidth;
  6. }

8. image问题

image组件,其实对于src图片路径,是以背景图展示的,并不是真的类似img,auto是不生效的。

9. wx.navigateBack返回无法传参数通知

wx.navigateBack返回通知上一页执行指定函数的作用,可以使用getCurrentPages()来获取上一页page对象,事先执行,如下:

  1. /* pages/order-detail/order-detail.js */
  2. //返回执行上一个页面的函数,good
  3. navigateBackFun: function(){
  4. var pages = getCurrentPages();
  5. var prevPage = pages[pages.length - 2];
  6. if(prevPage.__route__.indexOf("pages/order/order") != -1) {
  7. prevPage.actionCallback(this.data.btnAction,this.data.page);
  8. }
  9. }

10. class可以多组操作

  1. <view class="status-item {{index == orderData.progress.last_index? 'active' : ''}} {{index === orderData.progress.info.length - 1 ? 'last-status-item' : ''}}"></view>

11. 对于字体文件的使用

对于下面的字体文件的引用会导致报错,微信小程序似乎不支持怎么使用

  1. @font-face {
  2. font-family: 'Glyphicons Halflings';
  3.  
  4. src: url('/assets/fonts/glyphicons-halflings-regular.eot');
  5. src: url('/assets/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('/assets/fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('/assets/fonts/glyphicons-halflings-regular.woff') format('woff'), url('/assets/fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('/assets/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
  6. }

解决办法,将ttf文件拿出,转化成base64,以wxss引入。base64转化

12. 购物车功能

对于购车功能也是相当折腾的,通过在app.js定义全局变量:

  1. cartData:{
  2. list:[],
  3. totalCount:1,
  4. totalPrice:0,
  5.  
  6. // 起送价
  7. floorPrice:0,
  8.  
  9. // 总价达到此价免配送费
  10. freeShipPrice:0,
  11.  
  12. // 运费
  13. deliveryFee:0,
  14.  
  15. storeId:0,
  16. storeName:''
  17. }

然后每次加减产品,清空购物车来操作cartData的变化,list存储购物车产品数据,在首页和产品详情页,可以来获取购物车的数据,当然也会把购物车数据的商品id和门店id存储到Storage,可以用来异步更新最新的购物车数据,在首页和产品详情页的来回切换,对于购物车需要时刻去检查,映射到对应分类的swiper产品的加减变化,这里有没有像vue中vuex的状态管理能对数据集中管理,(对于vuex的使用 点击),导致监听变化变得很复杂,有把加减部件cart-ctrl和购物车cart提取成template模板组件,结果处理起来,这里一万个省略号,很悲催!github地址(欢迎star):https://github.com/xiaobinwu/dj

微信小程序实战练习(仿五洲到家微信版)的更多相关文章

  1. 前端微信小程序资讯类仿今日头条微信小程序

    需求描述及交互分析设计思路和相关知识点新闻频道滑动效果设计首页新闻内容设计首页新闻详情页设计我的界面列表式导航设计系统设置二级界面设计 设计思路(1)设计底部标签导航,准备好底部标签导航的图标和建立相 ...

  2. [转]微信小程序之购物车 —— 微信小程序实战商城系列(5)

    本文转自:http://blog.csdn.net/michael_ouyang/article/details/70755892 续上一篇的文章:微信小程序之商品属性分类  —— 微信小程序实战商城 ...

  3. [转]微信小程序之购物数量加减 —— 微信小程序实战商城系列(3)

    本文转自:http://blog.csdn.net/michael_ouyang/article/details/70194144 我们在购买宝贝的时候,购物的数量,经常是我们需要使用的,如下所示: ...

  4. [转]微信小程序之加载更多(分页加载)实例 —— 微信小程序实战系列(2)

    本文转自;http://blog.csdn.net/michael_ouyang/article/details/56846185 loadmore 加载更多(分页加载) 当用户打开一个页面时,假设后 ...

  5. 微信小程序实战之天气预报

    原文:微信小程序实战之天气预报 这个案例是仿UC中天气界面做的中间也有点出入,预留了显示当前城市名字和刷新图标的位置,自己可以写下,也可以添加搜索城市.值得注意的是100%这个设置好像已经不好使了,可 ...

  6. 微信小程序实战笔记

    前言: 微信小程序最近刚从鹅厂生产出来,我有幸参与了一次小程序的实战,有必要记录我的开发过程.看上去小程序很简单,但是在深入开发的时候才能具体体会里面的变化,接下来记录我的第一个微信小程序的点点滴滴! ...

  7. 【微信小程序】转载:微信小程序实战篇-下拉刷新与加载更多

    下拉刷新 实现下拉刷新目前能想到的有两种方式 1. 调用系统的API,系统有提供下拉刷新的API接口 当然,你可以直接在全局变量app.json的window里面配置上面这个属性,这样整个项目都允许下 ...

  8. 微信小程序实战篇:商品属性联动选择(案例)

    本期的微信小程序实战篇来做一个电商网站经常用到的-商品属性联动选择的效果,素材参考了一点点奶茶. 效果演示:   商品属性联动.gif 代码示例 1.commodity.xml <!-- < ...

  9. 微信小程序实战 购物车功能

    代码地址如下:http://www.demodashi.com/demo/12400.html 一.准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.com/ ...

  10. 微信小程序实战之百思不得姐精简版

    原文:微信小程序实战之百思不得姐精简版 微信小程序基本组件和API已撸完,总归要回到正题的,花了大半天时间做了个精简版的百思不得姐,包括段子,图片,音频,视频,四个模块.这篇就带着大家简述下这个小的A ...

随机推荐

  1. 项目添加大量js文件时关闭Eclipse校验机制

    1,如:当添加Ext JS的examples文件夹时

  2. 20190317 A

    今天是学长wsy的题,我理论会100+50+30=180,实际100+20+10=130,充分体现我的菜 最近日常模拟赛挂分50到60,很危险,这2天一定要调整好... Upd:T2我认为50的划分数 ...

  3. gjt常用命令---chalee

    Git常用命令 一. git 基本操作流程 1. 从远程分支拉取并创建新的分支 git pull origin [远程分支名]:[本地分支名] // 从远程分支迁出本地分支,并切换到新的本地分支 gi ...

  4. 常用sql语句总结(一)(查询)

    常用sql语句总结(一)(查询) 数据操作语句:DML 数据定义语句:DDL 数据控制语句:DCL (执行顺序------序号) 一.基本查询: 1. SELECT * ----- 2 FROM 数据 ...

  5. 分布式事物(同样适用于dubbo事务等分布式事务)

  6. IDEA 发布Api

    1.修改Main方法 代码: public class AlicsbapiApplication extends SpringBootServletInitializer { @Override pr ...

  7. redux&&createStore

    const createStore = (reducer,presetState, enhancer) => { if (typeof presetState === "functio ...

  8. C# 将对应的xml文档赋值给指定模型(对象)

    public static IList<T> XmlToEntityList<T>(string xml) where T : new()        {           ...

  9. P4116 Qtree3

    思路 可以树剖可以LCT,树剖就是每个重链开一个SET维护一下黑点的深度 非常不优美 使用LCT,在splay上二分找出需要的节点即可 代码 #include <cstdio> #incl ...

  10. APIO 2014 回文串(Manacher+后缀自动机+倍增)

    题意 https://www.lydsy.com/JudgeOnline/problem.php?id=3676 思路 好像还是回文自动机裸体,但是 \(\text{Manacher}\) +后缀自动 ...