github地址(欢迎star):https://github.com/xiaobinwu/djjavascript
css => 放置公用wxss,目前只有一个font.wcssphp
image => 静态资源目录css
lib => 第三方库(如:qqmap-wx-jssdk.min.js)vue
pages => 小程序页面(包括四个文件,.wxml/.wxss/.js/.json)java
template => 抽离出来的template,具备复用性git
utils => 工具类es6
app.js/app.json/app.wxss => 配置github
官方request代码:vuex
wx.request({ url: 'test.php', //仅为示例,并不是真实的接口地址 data: { x: '' , y: '' }, header: { 'content-type': 'application/json' }, success: function(res) { console.log(res.data) } })
可是有不少场景须要promise化的,因此使用第三方promise库(es6-promise.min.js),对request进行了一层包装:json
/* utils/util.js */ /* api接口promise 柯里化*/ var Promise = require('../lib/es6-promise.min.js'); function wxPromisify(fn, scope) { return function (obj = {}) { return new Promise((resolve, reject) => { obj.success = function (res) { resolve(res); } obj.fail = function (res) { reject(res); } if(scope){ //改变this指向 var newFn = fn.bind(scope); newFn(obj); }else{ fn(obj); } }) } } /* request 封装*/ var wxrequest = wxPromisify(wx.request); function wxRequest(options, tokenNotRequired){ return wxrequest(options).then(res => { var data = res.data; if(data.status === 404404) { if(tokenNotRequired){ delete options.headers; return wxRequest(options); }else{ return updateToken().then(token => { return wxRequest(object.assignIn(options, { headers: { 'X-Auth-Token': token } })); }); } }else { return Promise.resolve(data); } }).catch(err => { return Promise.reject(err); }); }
因为小程序默认给的微信地图api有些需求达不到要求,因而使用第三方库(qqmap-wx-jssdk.min.js,这是绝配),这样定位功能也比较好作,以及后续要作的地址管理模块也比较好下手,可是有个问题,对微信地图jdk接口进行promise化后,使用过程会报错,致使定位失败,因此须要改变其执行做用,因而对wxPromisify()方法作了些改造,从新绑定做用域至qqmapsdk,调用以下:
//address.js // 引入SDK核心类 var QQMapWX = require('../lib/qqmap-wx-jssdk.min.js'); // 实例化API核心类(须要配置安全域名https://apis.map.qq.com) var qqmapsdk = new QQMapWX({ key: 'xxxxx' //须要到腾地图上申请key }); ... ... // 请求用户受权定位 //逆地址解析 var ReverseGeocoder = util.wxPromisify(qqmapsdk.reverseGeocoder, qqmapsdk); //需改变做用域
对于小程序是须要配置对应的安全域名的,这样才能执行request
模板页(template)没有天生配对js,可是也能够实现,实现面向对象的思想,对模板所须要的js进行一层类的封装,保证构造函数须要接受父页面的上下文对象,而后能够把声明好的类方法绑定到父页面上面去,对于模板页js方法,以_FUN()方式命名。下面是为图片懒加载优化而作的swiper模板组件,能够参考一下。
/** * 图片预加载组件 * * @author xiaobin_wu * template/silder/silder.js */ class Slider { constructor(pageContext, options = { picList: [], showArr:[] }){ this.page = pageContext; //获取页面上下文 this.page.data.slider = { picList: options.picList, showArr: options.showArr }; //初始化data this.page._sliderChange = this._sliderChange.bind(this); } //监听滑动事件,实现图片懒加载 _sliderChange(e){ if(this.page.data.slider.showArr){ let showArr = this.page.data.slider.showArr; for(let i = 0; i < showArr.length; i++){ if(i === e.detail.current){ showArr[i] = true; } } this.page.setData({ 'slider.showArr': showArr }); } } initData(imgs){ const arr = new Array(imgs.length).fill(false); this.page.setData({ 'slider.picList': imgs, 'slider.showArr': arr.fill(true, 0 , 1) }); } } module.exports = Slider
以类形式module.exports出去,Page页面,以var Slider = require('../../template/slider/slider.js');
形式引入,而后new
操做,模板wxml也参考template/silder/silder.wxml
,也能够对应写wxss,这样作模板页复用性高,相似组件的模式。
刚开始使用scroll-view,scroll-x一直失效,不能水平scroll,折腾了好多时间,结果这样就成了,大概以下结构(home.wxml):
<scroll-view scroll-x="{{true}}" scroll-left="{{scrollLeft}}" class="scroll-bar" style="width:100%;" > <view style="width: {{idxData.navbar.length * 168}}rpx"> <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> </view> </scroll-view>
忽略其余乱起八糟的代码,主要是这个<view style="width: {{idxData.navbar.length * 168}}rpx">
,须要保证scroll-view下面的view的width必需要大于100%,充满整个scroll-view
因而对于红线部分的产品分类swiper,就只能手动计算swiper高度,来实现swiper的效果,可是因为对应每一个swiper-item还会有个下拉加载,因此产品数目会一直变化,因此计算起来至关于耗性能,但愿官方能尽快让swiper高度容许自动撑开
template模板,对象传递方式=>data={{a: x1,b: x2}}
,x一、x2对应data绑定的变量
可能你会遇到这种状况(设置动态数据):
this.setData({ 'array[0]': 1 }); /* 上面这样设置是没问题的,可是是动态的,那该怎么办?这样... */ this.setData({ 'array['+ index +']': 1 }); /* 很遗憾,没法怎么作 */
解决办法,声明中间量,以下:
/* utils/util.js */ //动态setData function dynamicSetData(field, index, value, suffix, type='object'){ var param = {}; var string = field + '[' + index + ']' + (typeof suffix !== 'undefined' ? type === 'object' ? '.' + suffix : '[' + suffix + ']' : ''); param[string] = value; return param; }
这样最后就能够这样,this.setData(util.dynamicSetData('firstLoadDataFlag', index, true));
,便可用于对象的改变,也能够用于数组的改变。
对于小程序中,也有一些组件须要传递变量单位为px的,若是这个变量是须要计算出来的,可是咱们使用的确是rpx单位,那么他们之间的转化比例是有必要知道的
/* utils/util.js */ //获取px与rpx之间的比列 function getRpx(){ var winWidth = wx.getSystemInfoSync().windowWidth; return 750/winWidth; }
image组件,其实对于src图片路径,是以背景图展现的,并非真的相似img,auto是不生效的。
wx.navigateBack返回通知上一页执行指定函数的做用,可使用getCurrentPages()来获取上一页page对象,事先执行,以下:
/* pages/order-detail/order-detail.js */ //返回执行上一个页面的函数,good navigateBackFun: function(){ var pages = getCurrentPages(); var prevPage = pages[pages.length - 2]; if(prevPage.__route__.indexOf("pages/order/order") != -1) { prevPage.actionCallback(this.data.btnAction,this.data.page); } }
<view class="status-item {{index == orderData.progress.last_index? 'active' : ''}} {{index === orderData.progress.info.length - 1 ? 'last-status-item' : ''}}"></view>
对于下面的字体文件的引用会致使报错,微信小程序彷佛不支持怎么使用
@font-face { font-family: 'Glyphicons Halflings'; src: url('/assets/fonts/glyphicons-halflings-regular.eot'); 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'); }
解决办法,将ttf文件拿出,转化成base64,以wxss引入。base64转化
对于购车功能也是至关折腾的,经过在app.js定义全局变量:
cartData:{ list:[], totalCount:1, totalPrice:0, // 起送价 floorPrice:0, // 总价达到此价免配送费 freeShipPrice:0, // 运费 deliveryFee:0, storeId:0, storeName:'' }
而后每次加减产品,清空购物车来操做cartData的变化,list存储购物车产品数据,在首页和产品详情页,能够来获取购物车的数据,固然也会把购物车数据的商品id和门店id存储到Storage,能够用来异步更新最新的购物车数据,在首页和产品详情页的来回切换,对于购物车须要时刻去检查,映射到对应分类的swiper产品的加减变化,这里有没有像vue中vuex的状态管理能对数据集中管理,(对于vuex的使用 点击),致使监听变化变得很复杂,有把加减部件cart-ctrl和购物车cart提取成template模板组件,结果处理起来,这里一万个省略号,很悲催!github地址(欢迎star):https://github.com/xiaobinwu/dj