网友真实露脸自拍10p,成人国产精品秘?久久久按摩,国产精品久久久久久无码不卡,成人免费区一区二区三区

小程序模板網

微信小程序版五洲到家實戰

發布時間:2017-12-13 09:09 所屬欄目:小程序開發教程

微信小程序版五【五洲到家】實戰及操作中遇到的坑。

 
 
 

微信小程序實戰 
版本:0.15.152900(暫未升級原因:升級后需要圖片無法本地引用,必須使用image或是遠程路徑引用)

先上一波gif圖片

cmd-markdown-logocmd-markdown-logocmd-markdown-logocmd-markdown-logocmd-markdown-logocmd-markdown-logocmd-markdown-logocmd-markdown-logo

 

gif對應功能塊

 

		
  1. 首頁(定位成功情況且有門店)
  2. 門店列表(定位成功情況卻沒有門店)
  3. 更多(定位沒有成功情況也沒有門店)
  4. 產品詳情頁
  5. 門店詳情
  6. 更多門店
  7. 訂單及訂單詳情
  8. 個人中心
  9. 目錄結構

踩過的坑

1. promise封裝

官方request代碼:

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進行了一層包裝:

/* 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);
    });
}

2. Javascript作用域問題

由于小程序默認給的微信地圖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

3. 如何衍生出組件模板

模板頁(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,這樣做模板頁復用性高,類似組件的模式。

4. scroll-view使用scroll-x失效問題

剛開始使用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

4. swiper高度無法自動撐開,暫時不支持


于是對于紅線部分的產品分類swiper,就只能手動計算swiper高度,來實現swiper的效果,但是由于對應每個swiper-item還會有個下拉加載,所以產品數目會一直變化,所以計算起來相當于耗性能,希望官方能盡快讓swiper高度允許自動撐開

5. template模板

template模板,對象傳遞方式=>data={{a: x1,b: x2}},x1、x2對應data綁定的變量

6. setData設置動態數據

可能你會遇到這種情況(設置動態數據):

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));,即可用于對象的改變,也可以用于數組的改變。

7. 設置頂層標簽Page的樣式,處理安卓機的背景色問題

8 px與rpx之間轉化

對于小程序中,也有一些組件需要傳遞變量單位為px的,如果這個變量是需要計算出來的,但是我們使用的確是rpx單位,那么他們之間的轉化比例是有必要知道的

/* utils/util.js */
//獲取px與rpx之間的比列
function getRpx(){
    var winWidth = wx.getSystemInfoSync().windowWidth;
    return 750/winWidth;
}

8. image問題

image組件,其實對于src圖片路徑,是以背景圖展示的,并不是真的類似img,auto是不生效的。

9. wx.navigateBack返回無法傳參數通知

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);
  }
}

10. class可以多組操作

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

11. 對于字體文件的使用

對于下面的字體文件的引用會導致報錯,微信小程序似乎不支持怎么使用

@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轉化

12. 購物車功能

對于購車功能也是相當折騰的,通過在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模板組件,結果處理起來,這里一萬個省略號,很悲催!

13. require原理

微信小程序類似瀏覽器一樣,借助一個HTML頁面來引用加載所有的JS文件,但是并不會馬上去執行,代理服務部分代碼又怎么兩個全局函數define和require,類似amd,使用define函數對請求回來的js文件內容進行包裝,但是不去執行,然后可以使用require函數按需遞歸式進行初始化,這個時候js就會執行了,并且只執行一次,那么對于Page頁面為什么js能一開始不使用require函數就能加載呢?因為默認page頁面js文件,會自動添加上require自己,加載后立即初始化。這樣是不需要擔心多次require會執行多次js的。
這篇文章寫得很詳細 微信小程序的require機制淺析,順便貼一下幾段代碼(幫助理解):

代理服務部分代碼:
(projectManager.js)
function getScripts(projInfo, callback) {
  ...
    fs.readFile(fname, 'utf8', function(err, scripts) {
        ....
        scripts = 'define("' + moduleName + '", function(require, module, exports, ' + noBrowserStr +
        '){ ' + scripts + '\n});',
        needRequire && (scripts += 'require("' + moduleName + '")'), //page頁面js文件,會添加上require自己,加載后立即初始化。
        .....
        callback(null, scripts) //scripts串內容作為HTTP GET的返回
    var 
    ......
    moduleList = {}; 
    define = function(moduleName, factory) {  //define是全局函數,每個JS文件都默認會調用. 
        moduleList[moduleName] = { status: status1, factory: factory }
    };
 
....
    require = function(moduleName) {       
        ....
        var module = moduleList[moduleName]; //define函數調用時為moduleList賦的值
        .....
        if (module.status === status1) {  
            //如果未初始化,則初始化
            var factory = module.factory,  //這個factory就是這個JS文件的腳本.
            obj = { exports: {} }, u = void 0;
            factory && (u = factory(o(moduleName), obj, obj.exports)), module.exports = obj.exports || u, module.status = status2
        }
        return module.exports
    }


易優小程序(企業版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://www.xiuhaier.com/wxmini/doc/course/18161.html 復制鏈接 如需定制請聯系易優客服咨詢:800182392 點擊咨詢
QQ在線咨詢
AI智能客服 ×