送給寫小程式的你。

Jiyr發表於2018-05-29
 

宣告:本人也是菜鳥一隻,寫的不好的地方,大佬們指點指點。

歡迎來點點我的部落格

微信小程式商城,持續更新。(已經跳槽了,但是還是小程式相關的專案/斜眼)

先說說寫小程式的淵源吧,我之前認識的大佬寫了一個比較簡單的小程式,我改了改樣式於是成功的有了我的第一個小程式。然後我在找工作的時候,簡歷上寫了這麼一回事,結果進來之後,leader語重心長的對我說,公司的小程式商城就教給你了,重點是公司沒有一個人會微信小程式。WTF,不是招我進來寫VUE的嗎?

於是就開始了我從零開始寫微信小程式商城之路。

微信小程式的官方文件什麼的我就不說了,那是肯定要看的。說說我這幾天開始寫我遇到的問題。希望對將要寫小程式的你能有一絲絲幫助,因為本人也很菜。

1、微信小程式之rpx

在微信官方的文件中,我們看到這樣一句話:

在 iPhone 6 上,螢幕寬度為 375px,共有 750 個物理畫素,則 750rpx = 375px = 750 物理畫素,1rpx = 0.5px = 1 物理畫素。開發微信小程式時設計師可以用 iPhone 6 作為視覺稿的標準。也就是說,設計師在設計小程式時,可以這樣做:

  • 直接以 iPhone 6 的螢幕尺寸(375×667)用作視覺稿尺寸,1 px = 0.5 rpx;
  • 以 1 px = 1 rpx 的標準,將設計稿尺寸設定為 750×1334。

其實總的來說就是,你跟UI小姐姐說一聲,然後就可以很爽的寫樣式了。

2、微信小程式之容器檢視

  • view 其實就是div,嘿嘿嘿就是這麼簡單粗暴的解釋。
  • scroll-view 可滾動檢視區域。 這個需要注意的是,橫向滾動的檢視區域。重要的是這兩個行內樣式,其他的官方文件也說的比較清楚。

<view class="supply-scroll bg">
<scroll-view class="scroll-box" scroll-x="true" style="width: 100%;white-space: nowrap; display: flex" >
<view class="scroll-items" wx:for="{{scrollList}}" wx:key="index" data-index="{{index}}" style="display: inline-block">
<image src="{{item.url}}" class="scroll-image"/>
</view>
</scroll-view>
</view>

3、微信小程式之UI框架

這個,很有意思,當我寫完一個我覺得很有靈性的選項卡的時候,以前哥們告我微信小程式有個框架你看看去。。。

<view wx:for="{{tab}}" wx:key="index" data-id="{{item.id}}" data-index="{{index}}"
bindtap="switchTab" class="tab-list {{tabIndex === index?'on':''}}">
{{item.name}}
</view>

送給寫小程式的你。


不BB,直接上地址 github.com/Tencent/weu…


送給寫小程式的你。

先寫到這裡,週六加班的午休時間,冒著被同時打死的危險寫的,如果有什麼寫的不好的地方,請大家多多包涵,我也還會分享我遇到的問題。

最近又看到有讚的微信小程式UI還是老規矩直接上地址:

youzan/zanui-weapp

4、微信小程式之switchTab

頁面跳轉大家官網上看的navigator用法你套著用就可以了,今天分享一下我在小程式中遇到的頁面跳轉的問題。我寫的是一個電商商城小程式,跳轉到詳情頁之後有兩個點選跳轉的icon如圖:

送給寫小程式的你。

聰明的你肯定猜出來這兩個icon是跳轉到哪的,肯定也是bindtap,然後wx.navigator就搞定了。兩個簡單的頁面跳轉嘛,然後居然就是這兩個問題卡了我一個多小時,後來還是在微信群裡問大佬們才解決的,因為自己看文件不仔細,跳轉的這兩個頁面是微信官方底部tab的路徑如圖:

送給寫小程式的你。

問題是出在官方的tabbar中你用了這幾個路徑如圖:

送給寫小程式的你。

然後解決方法為:

handleGoIndex: function() {
wx.switchTab({
url: '/pages/index/index'
})
},
handleGoCart: function() {
wx.switchTab({
url: '/pages/cart/index'
})
}

5、微信小程式之禁止頁面下拉

有的時候你會遇到不讓頁面下拉,如果你以為我說的是下拉重新整理的api的話那就圖樣了。就是不讓你下滑的時候出來那個白條。直接上程式碼了:

<view catchtouchmove="stopDrag" class="container">
stopDrag(){
return false;
},

但是這個慎用,我也想在這裡如果有大神能指點指點就最好了,這個的效果是可視區域全部靜止滑動... 拼多多的小程式首頁就是不會出現那個下拉的白條,但能上滑看商品資訊,求教~

送給寫小程式的你。
最新解決方法,在app。json 裡面增加一條這個屬性,就可以禁止滾動。

6、微信小程式之頁面深度

在測試自己的專案的時候,發現明明邏輯沒問題,語法也沒問題。突然想起來小程式的頁面棧是五個,於是特別中二的數了一下自己的頁面跳轉哈哈... 才發現當時自己的理解是錯誤的,剛開始不細心看文件,我以為這五個頁面是超過五個會把新的加進頁面棧,第一個開啟的銷燬。我就無腦用wx.navigateTo,遇到這個問題後用了 wx.redirectTo就解決了。但是誰讓我好學呢,於是發現一個大神寫的特別完美的理解小程式頁面跳轉的原理。

(現在深度,變成了10層,但是在ios 10的部分系統下,還是有bug的,還是要考慮頁面深度這種場景的。)

依然是嘿嘿:小程式基礎篇之頁面路由-微信小程式俱樂部 www.wxappclub.com

7、微信小程式之上拉載入

我現在公司的專案做的是電商的小程式,下拉重新整理,官網寫的很明確不能與scroll-view同時使用。我是在腦子瓦特的情況下,onReachBottom 和 scroll-view的bindscrolltolower 都用了。經過我的實踐,推薦大家用 onReachBottom。如果是一些tab裡面也有下拉重新整理,這個就很方便直接上程式碼:

onReachBottom() {
        let isPush = this.data.index,
            val = this.data.inputVal;
        this.setData({
            isBtnShow: true
        });
        if (isPush ==1) {
            let num = this.data.limitIndex;
            this.setData({
                limitIndex: num+1
            })
        //關於上拉載入的效能優化
            setTimeout(()=>{
                    // 給後端傳下拉重新整理的次數+1
                    const data = {
                        limitIndex: this.data.limitIndex
                    };
                    utils.sendRequest(api.AllGoodsUrl, data, this.handleReachBottom.bind(this));
            },1500)
        };
        if (val != '') {
            setTimeout(()=>{
                let num = this.data.limitIndex;
                    this.setData({
                        limitIndex: num+1
                    })
                    // 給後端傳下拉重新整理的次數+1
                    const data = {
                        limitIndex: this.data.limitIndex,
                         data:{
                            name: this.data.inputVal,
                        }
                    };
                    utils.sendRequest(api.AllGoodsUrl, data, this.handleLoadMore.bind(this));
            },1500)
        };
    },
這段程式碼主要就是判斷tab的狀態來延時請求介面。實現效果如下圖:
複製程式碼
送給寫小程式的你。
送給寫小程式的你。

這就是我用上拉載入的實踐,希望有大神能提出更好的建議。

8、微信小程式之資料互動

說到這裡順便把我的一些關於資料互動的一些經驗分享一下

function sendRequest(path, data, callback) {
    wx.request({
        url: path, 
        data: data,
        header: {
            'content-type': 'application/json'
        },
        method: "POST",
        success: callback,
        fail:(res)=>{
          console.log(res)
        }
    })
}  把微信請求封裝起來
還有專案裡面要用到的介面如下
//promise 方式
function promiseRequest(url, data = {}) {
  return new Promise(function (resolve, reject) {
    wx.request({
      url: url,
      data: data,
      method: 'POST',
      header: {
        'Content-Type': 'application/json',
      },
      success:(res) => {
        if (res.statusCode == 200) {
            resolve(res);
        } else {
          reject(res.errMsg);
        }

      },
      fail: (err) => {
        reject(err)
        console.log("failed")
      }
    })
  });
}
新增  promise  請求方式
        //沒有引數就傳空
  utils.promiseRequest(api.BannerUrl).then(res => {
      if(res.data.error == 0){
        //dosomething。。。
      }else {
          utils.showModal(res.data.err_msg)
      }
  });
複製程式碼
送給寫小程式的你。
把介面暴露出去在其他頁面呼叫
送給寫小程式的你。
送給寫小程式的你。

希望有大神能幫忙一下小程式的元件化最佳實踐~

9、微信小程式之Android請求失敗的坑

我當時遇到的情況是,在模擬器和IOS環境下請求資料都是沒有任何問題的,在測試android環境時發現請求失敗如下圖

送給寫小程式的你。

這個錯還讓我跟運維的大哥撕了半天哈哈, 首先出現這個錯,兄弟這個鍋完完全全就能甩給運維的大哥,不留任何餘地。 然後可以幫大哥提供一寫資料,一步步排查,先查你專案繫結域名:

1、https證照問題 :ssl證照配置需要使用pem,不使用crt, ,

2、伺服器端的版本資訊:TLS版本的問題,該問題在微信小程式官方文件中已經提及到,伺服器TLS版本必須支援 1.2 (啟用1.2,禁用1.1和1.0等低版本),

3、前兩種方法是在查閱資料有人說是可解決的,但是對於我們公司最後在排查前兩項之後,運維大哥用Nginx轉發了之後,解決了安卓請求失敗的問題。希望可以幫到大家吧~

10、微信小程式之地址頁面三級聯動

說道這個問題,現給大家貼一個地址,非常感謝大神的開源:blog.csdn.net/sinat_17775…

大家可以看到程式碼之後,先理清你要處理的後端資料和存地址的要求等等,我遇到的問題是


送給寫小程式的你。


後端給我的資料裡面有每一個地址對應的ID,比如北京:2 北京:50 東城區:500

處理這個資料的時候,我根據原來大神的程式碼做了一些修改,

let val = e.detail.value,
            t = this.data.values,
            cityData = this.data.cityData,
            index = this.data.id,
            list = this.data.addrList;
            list[index].area = true;
            try {
                if (val[0] != t[0]) { //當val是選擇省份的時候
                const citys = [];
                const countys = [];
                    cityData[val[0]].child.map(item => citys.push({name:item.name,id:item.id}));
                    cityData[val[0]].child[0].child.map(item => countys.push({name:item.name,id:item.id}));
                    list[index].provinceName = this.data.provinces[val[0]].name;//省份
                    list[index].cityName = cityData[val[0]].child[0].name;//城市
                    list[index].districtName = cityData[val[0]].child[0].child[0].name;//地區
                    list[index].province = this.data.provinces[val[0]].id;//對應的傳值ID
                    list[index].city = cityData[val[0]].child[0].id;//對應的傳值ID
                    list[index].district = cityData[val[0]].child[0].child[0].id;//對應的傳值ID
                this.setData({
                    citys: citys,
                    countys: countys,
                    values: val,
                    value: [val[0], 0, 0],
                    addrList: list
                })
                    return;
                }
                if (val[1] != t[1]) {//當val是選擇城市的時候
                    const countys = [];
                    cityData[val[0]].child[val[1]].child.map(item => countys.push({name:item.name,id:item.id}));
                    list[index].cityName = this.data.citys[val[1]].name;// 選擇城市
                    list[index].city = this.data.citys[val[1]].id;//對應的傳值ID
                    list[index].districtName = cityData[val[0]].child[val[1]].child[0].name;//選擇城市對應的地區
                    list[index].district = cityData[val[0]].child[val[1]].child[0].id;//對應的傳值ID
                    this.setData({
                        countys: countys,
                        values: val,
                        value: [val[0], val[1], 0],
                        addrList: list
                    })
                    return;
                }
                if (val[2] != t[2]) {//當val是選擇地區的時候
                    list[index].districtName = this.data.countys[val[2]].name;//選擇地區
                    list[index].district = this.data.countys[val[2]].id;//對應的傳值ID
                    this.setData({
                        county: this.data.countys[val[2]].name,
                        values: val,
                        addrList: list
                    })
                    return;
                }    

            } catch(e) {
                // statements
                console.log(e);
            }
list裡面是有 收貨人,電話,等等資訊  但是我只操作改變陣列裡面地址改變的資訊,
複製程式碼



送給寫小程式的你。



佈局方面需要做一些修改的地方就是



送給寫小程式的你。
送給寫小程式的你。

我貼了這麼多圖,是因為我真不會說了,調這個頁面調了兩天。只能提供個大概方向,還是得一步步處理資料,goodluck~

11、微信小程式之Android環境下的橫向滾動

<view class="tab bg">
          <scroll-view class="" scroll-x="true" style="width: 100%;white-space: nowrap; display: flex;overflow-x: auto;">
              <view style="display: inline-block" bindtap="switchIndex" class="tab-list {{index === 1 ?'on':''}}">首頁</view>
              <view wx:for="{{tab}}" wx:key="index" data-id="{{item.id}}" data-index="{{index}}"
                 style="display: inline-block" bindtap="switchTab" class="tab-list {{tabIndex === index?'on':''}}">
                  {{item.nav_name}}
              </view>
          </scroll-view>
      </view>
程式碼一貼其實當測試小哥告訴你安卓tab不能滑的時候,你只需要加一個overflow-x: auto;哈哈哈
複製程式碼

12、微信小程式之Ios環境下mp4播放問題

當你遇到你的mp4格式有的能播放,有的不能播放的話,你只需要看一下你的mp4編碼格式,必須是h264格式才行。

13、微信小程式之微信支付的坑

這個因為我也是第一次寫小程式嘛,後端的大哥,在H5的商城裡什麼都實現了一次了,非說各種沒問題,只貼兩個圖就明白了第一個

送給寫小程式的你。
這個api裡面的所有資料都是後端返給你的,不要接受他的甩鍋哈哈。

還有就是一定要讓後端好好看微信支付的文件,一般公司開發商城都是服務商版的支付服務,這裡就是我和後端大哥的甩鍋之路,他沒有繫結我得小程式appid,然後各種說調不通。。。

送給寫小程式的你。

去這裡配置好,前端只需要調API傳值就好

14、微信小程式之圖片上傳

好久沒更新了,被公司業務搞得焦頭爛額。

老規矩,直接上程式碼了。

handleCancelPic() {
        let id = this.data.dbId;
        wx.chooseImage({
          count: 3, // 預設9
          sizeType: ['compressed'], // 可以指定是原圖還是壓縮圖,預設二者都有
          sourceType: ['album', 'camera'], // 可以指定來源是相簿還是相機,預設二者都有
          success: res => {
            // 返回選定照片的本地檔案路徑列表,tempFilePath可以作為img標籤的src屬性顯示圖片
            var tempFilePaths = res.tempFilePaths;

            this.setData({
                src: tempFilePaths
            })
            upload(this,tempFilePaths,'','');
          }
        })
    }
然後一個封裝好的方法
function upload(page, path,way,id) {
    console.log(path)
  wx.showToast({
    icon: "loading",
    title: "正在上傳"
  });
  var test = [],
    that = this;
  for (var i = 0; i<path.length; i++) {
        wx.uploadFile({
          url: api.CancelImg,
          filePath: path[i],          
          name: 'file',
          header: { "Content-Type": "multipart/form-data" },
          success: res => {
            test.push(res);
            wx.setStorageSync('cancelImg',test)
            console.log(test)
            if (res.statusCode != 200) { 
              wx.showModal({
                title: '提示',
                content: '上傳失敗',
                showCancel: false
              })
              return;
            }else {
                wx.showModal({
                    title: '提示',
                    content: '上傳成功',
                    showCancel: false
                }) 
            }
          },
          fail: function (e) {
            console.log(e);
            wx.showModal({
              title: '提示',
              content: '上傳失敗',
              showCancel: false
            })
          },
          complete: function () {
            wx.hideToast();  //隱藏Toast
          }
        })
    }
這個是多個圖片上傳的方法,單個圖片上傳的話,把迴圈去掉就好。主要是因為微信官方預設的就是一次上傳一張圖片這個很蛋疼。只能這麼搞了。。。
複製程式碼

15、微信小程式之電商購物車邏輯

接著再給大家分享一個關於小程式購物車全選的邏輯處理,這個還是要感謝我的老妹教導我,一個開發人員做東西一定要嚴謹,不管UI設計的有多醜,該有的邏輯你一定要做到。

送給寫小程式的你。

首先我們要做到的就是,當使用者點選第三個商品時 全選按鈕自動選中,或者全選之後,只要有一個商品不選中,全選按鈕也得變動。先給大家看一下程式碼:

你要在頁面onload時候定義一些你需要每次渲染的資料

data: {
likeList: [],
carts:[], // 購物車列表
hasList:false, // 列表是否有資料
//totalPrice:0, // 總價,初始為0
selectAllStatus:false, // 全選狀態,預設全選,
goodsNums:0,
allclick:[]
}
每件商品單個選中的的邏輯處理
selectList(e) {
  const index = e.currentTarget.dataset.index;// 獲取每一個點選的購物車ID
  let carts = this.data.carts,
  selected = carts[index].select,
  all = this.data.allclick;
  carts[index].select = !selected;
carts[index].select == true ? all.push(index):all.splice(index,1);
all.length == carts.length ?
this.setData({
  selectAllStatus: true
}):this.setData({
  selectAllStatus: false
});
  this.getTotalPrice();
},
上面的程式碼,先做的就是單選的頁面渲染效果。判斷部分的程式碼就是最主要的處理全選邏輯的一步。相信你看到這裡也注意到我在data裡定義了一個allclick的空陣列,然後就是接下來的邏輯:
複製程式碼
  • 按鈕選中時取出對應item的角標放到新的arr裡,這裡因為我之前結算的邏輯已經搞好了,我就隨便往陣列裡push資料,但其實可以作為對應商品的更重要的一些資料處理。
  • 按鈕不選中是從新的arr裡找到這個item對應下標的資料移除
  • 完成上面兩步處理之後,每次按鈕狀態發生變化的時候判斷arr的長度和cart的長度。

這就是我的處理,也可迴圈,實現的方式有很多,只是拿出來讓沒有接觸過的小夥伴做個參考~

data: {
likeList: [],
carts:[], // 購物車列表
hasList:false, // 列表是否有資料
//totalPrice:0, // 總價,初始為0
selectAllStatus:false, // 全選狀態,預設全選,
goodsNums:0,
allclick:[]
}
每件商品單個選中的的邏輯處理
selectList(e) {
  const index = e.currentTarget.dataset.index;// 獲取每一個點選的購物車ID
  let carts = this.data.carts,
  selected = carts[index].select,
  all = this.data.allclick;
  carts[index].select = !selected;
carts[index].select == true ? all.push(index):all.splice(index,1);
all.length == carts.length ?
this.setData({
  selectAllStatus: true
}):this.setData({
  selectAllStatus: false
});
  this.getTotalPrice();
},
這段程式碼也還是先處理全選的狀態,然後就是關聯狀態的處理,
複製程式碼
  • 當全選沒有勾選的時候全部改變商品資訊裡的按鈕為false,直接清空allclick陣列。
  • 當全選勾選的時候全部改變商品資訊裡的按鈕為true,先清空,接著重新push,再賦值。

經過這幾步操作之後就解決了全選這方面的所有邏輯,覺得有用的小夥伴,記得評論,關注喲~

16、微信小程式之使用Map物件

這是我的樑master跟我提的這件事,我是小程式,她是Android,專案一樣。我倆關係好,然後她教我的用的這個Map物件,其實這個是java的map物件。用起來真的很爽,不廢話了直接上程式碼。

這個在es6的標準裡面也推出了Map物件。借用阮大神書裡面的一段話:

JavaScript 的物件(Object),本質上是鍵值對的集合(Hash 結構),但是傳統上只能用字串當作鍵。這給它的使用帶來了很大的限制。

const data = {};
const element = document.getElementById('myDiv');
data[element] = 'metadata';
data['[object HTMLDivElement]'] // "metadata"

上面程式碼原意是將一個 DOM 節點作為物件data的鍵,但是由於物件只接受字串作為鍵名,所以element被自動轉為字串[object HTMLDivElement]。
為了解決這個問題,ES6 提供了 Map 資料結構。它類似於物件,也是鍵值對的集合,但是“鍵”的範圍不限於字串,各種型別的值(包括物件)都可以當作鍵。也就是說,Object 結構提供了“字串—值”的對應,Map 結構提供了“值—值”的對應,是一種更完善的 Hash 結構實現。如果你需要“鍵值對”的資料結構,Map 比 Object 更合適。複製程式碼

感興趣的小夥伴可以移步es6入門 map set

let localMap = new Map(),// 定義一個全域性的MAP物件 
typeCode = ''; // 點選分類裡面的細分選項卡
handleClickTabs(e) {
 let id = e.target.dataset.index,
 code = e.target.dataset.id; 
typeCode = code;// 這裡定義code,在請求回撥裡面使用 
this.setData({ leftTab : id }); 
if (localMap!=null) {// map物件 
let list = localMap.get(typeCode);//獲取對應分類的type的code 
if (list!=null) {//map裡面有值,渲染頁面 
this.setData({ tabSonList:list }) }else {//map裡面沒有值,去請求介面 const data = { goodsTypeCode: code }; 
utils.sendRequest(api.ClassifySon, data, this.handleGoodsSon.bind(this)); }
 }else { const data = { goodsTypeCode: code }; 
utils.sendRequest(api.ClassifySon, data, this.handleGoodsSon.bind(this)); } }, //分類裡面的內容 handleGoodsSon(res) {
 let list = res.data; localMap.set(typeCode,list)//存對應typeCode的list 
this.setData({ tabSonList:list }) },
複製程式碼
送給寫小程式的你。

這樣就實現了,對選項卡的優化,如果介面資料變多了的話,會重新賦值。 雖然是自己給自己加戲,但這是也是我的一種工作態度,學習了新東西,還讓優化了專案。

17、小程式之全域性變數快取的問題

這個問題的出現是因為,在input的事件,我沒有找到更好的能監聽鍵盤收回的方法,也是為了更好的使用者體驗吧,所以隨之而來的問題就是全域性變數,在賦值之後使用者退出這個頁面,全域性變數被微信快取了,然後造成,使用者輸入過一次之後,修改手機號失敗的bug。

送給寫小程式的你。
let Btel = '',//防止使用者惡意修改手機號
    Byzm = '';

handleTel(e) {// 這裡修改使用者輸入的手機號
        this.setData({
            tel:e.detail.value 
        })
    },
    handleYzm(e) {
        this.setData({
            Yzm:e.detail.value
        })
        Byzm = e.detail.value;
        let psd = this.data.psd,
            yzm = this.data.Yzm;
        yzm == psd ? this.setData({isYzm:0}):'';
    },
    handleGetYzm() {
        let reg = common.telReg,
            val = this.data.tel;    
        if (!reg.test(val)) {
               wx.showModal({
                content:'請輸入正確的手機號',
                showCancel:false,
                confirmColor:'#3cc51f',//預設值為#3cc51f
                success:res =>{
                    if(res.confirm){
                        this.setData({
                            tel:''
                        })         
                    }
                }
            })
        }else {//傳送驗證碼的時候用全域性變數的手機號
            Btel = val;// 這裡是全域性的手機號    
            this.setData({
                isReset : true,
                isNoClick: true
            })
            const data ={
                tel:val//傳的是全域性變數 
            };
            utils.sendRequest(api.YanZhengMa, data, this.handleGetYzmSucc.bind(this));
            //button 定時器
            let time = setInterval(()=>{
            let phoneCode = this.data.time;
                phoneCode --
                this.setData({
                    time : phoneCode
                })
                if(phoneCode == 0){
                     clearInterval(time)
                     this.setData({
                        isReset : false,
                        isNoClick: false,
                        time:60
                     })
                }
            },1000)
        }
        
            
    },

//然後這一步是校驗了使用者在請求完驗證碼介面後 有沒有修改手機好 然後儲存
handleSave() {
        let name = this.data.name,
            telNum = this.data.tel,
            yzm = Byzm,
            status = this.data.isYzm,
            card = wx.getStorageSync('UserCard');
        let timestamp= new Date().getTime();
        if (yzm == '') {
            wx.showModal({
                content:'請輸入驗證碼.',
                showCancel:false,
                confirmColor:'#3cc51f'
            })
            return false;
        }
        if (name!=''&&telNum!='') {
            if(Btel != telNum) {
                utils.showModal('手機號發生變化,請重新獲取驗證碼。');
            }else {
                const data ={
                distribution_id:card.distribution_id,
                post:{
                    user_name:name,
                    user_tel:Btel,
                    user_code:yzm
                },
                user_id:card.user_id,
                password:yzm+timestamp
                };
                utils.sendRequest(api.BindTel, data, this.handleSaveTel.bind(this));
            }
        }else {
            utils.showModal('請填寫完整資訊喲');
        }
    },

// 然後在 儲存成功之後 使用者點選確定  清空 全域性變數  也可以在隱藏和解除安裝的生命週期裡面清空全域性變數。
handleSaveTel(res) {
        if (res.data.error == 0) {
            let go = this.data.go,
                id = res.data.data.id,
                lv = res.data.data.level;
            wx.showModal({
                content:'繫結成功~',
                showCancel:false,
                confirmColor:'#3cc51f',//預設值為#3cc51f
                success:res =>{
                    if(res.confirm){
                        Byzm = '';//對小程式全域性變數快取進行清除
                        if (go) {
                            wx.redirectTo({
                              url: '/pages/user/cash/cash'
                            })
                        }else {
                            if (id != 0) {
                                let card = wx.getStorageSync('UserCard');
                                card.distribution_id = id;
                                card.distribution_level = lv;
                                wx.setStorageSync('UserCard',card);
                                wx.setStorageSync('seller', true)
                            }
                            wx.switchTab({
                              url: '/pages/user/index'
                            })
                        }         
                    }
                }
            }) 
            return false
        }else {
            utils.showModal(res.data.err_msg);
        }
    }
複製程式碼

18、小程式之微信支付的深坑

事情是這樣的,因為公司主體變更,避稅之類的事。我們公司的小程式,需要重新換綁微信支付,在財務給我們申請號商戶號之後,我們排期半夜來切環境。 我記得是一個週四的晚上,十二點開始切環境,然後 大概後端程式碼資料庫都準備好之後,我們重新繫結微信支付,以為大功告成。週五還能彈性一上午美滋滋~

沒想到 剛交個測試,說微信支付不能用,提示我們沒有授權。wtf,剛繫結好的你這樣提示,不合適吧。按照報錯一查,我去小程式 社群裡一看。

你敢信,微信開放平臺的商戶號和公眾號商戶號,是兩回事。 小程式之支援公眾號的商戶號,但是你在開放平臺繫結小程式微信支付的時候,官方給你的提示是 繫結成功~。

然後 就變成了 早上七點下班。。。

血的教訓呀!!!

19、小程式之登陸改版

https://juejin.im/post/5b0e9c6351882515887ed760

嘿嘿,寫完貼個地址得了~

20、小程式之webview在ios下訪問不到的坑

ios端小程式有的頁面白屏,後來查到的問題是web-view的src中攜帶的引數中含有中文,ios端是不允許連結中有中文的,所以只能給中文轉碼了,h5頁面提取引數的時候再解碼一下就可以了 

1 中文轉碼

encodeURI(url)1複製程式碼

2 解碼

decodeURI(url)複製程式碼

還有一些關於webview的知識點

  1. 每個頁面只能有一個<web-view/>,<web-view/>會自動鋪滿整個頁面,並覆蓋其他元件,小程式對webview的監控狀態基本沒有,只能設定src設定url。
  2. 關於小程式和web-view的通訊,<web-view/> → 小程式只能通過JSSDK 1.3.0提供的介面返回小程式頁面,設定引數來傳值,反之,小程式到webview也是一樣的,只能是src的路徑帶上引數;
  3. web-view不支援支付能力,是指無法喚起小程式的直接支付視窗,對於h5的那套支付應該是支援的,但是web-view 裡邊沒法使用 微信支付的 JSAPI,也就是可能可以h5的相關的的支付中心來支付;
  4. 關於層級,在webview中可以無限跳轉,對於導航條返回和物理鍵返回都會回到上一個頁面直到退出webview,就像history.back
  5. webview中的html的title會自動放到小程式的頭部作為標題;

21、小程式之呼叫上個頁面方法

因為,現在的專案是小程式巢狀h5,金融類目,做人臉識別 在小程式,然後購買理財、存款之類的在h5裡面,識別之後要根據原來的路徑就回到原來的h5頁面。

記得官方文件上面說過getCurrentPages() 不要改變路由,但是也能獲取到頁面的方法,於是就可以實現我的需求嘍。程式碼如下:

let pages = getCurrentPages();      
let lastpage = pages[pages.length - 2]      
if (lastpage.route === "pages/webview/webview") {        
        lastpage.changeUrl();        
    setTimeout(() => {          
        clearInterval(this.data.time);          
        wx.navigateBack({})        
    }, 500)     
 }複製程式碼

然後我只需要在我webview的js裡面寫更換去h5的路由:

  changeUrl() {    
        if (wx.getStorageSync('faceSucc')) {      
            let url = app.config.h5url + "/" + Util.formatParm(app.globalData.face_retCode, app.parm.h5_servid_url);      // console.log(app.globalData.header)      // url = url + "?param=" + encodeURIComponent(JSON.stringify(app.globalData.header))      // 快取bug      
            if (url.indexOf("?") !== -1) {        
                url = url + "&d=" + new Date().getTime()      
            } else {        
                url = url + "?d=" + new Date().getTime()      
            }      
            this.setData({        
                url: url      
            })    
        }  
    },複製程式碼

就可以在back的時候 已經修改了 上個頁面的 h5的路由。是不是很方便呢。

22、小程式之使用AES加密和NPM

專案需要aes加密,找了一下前端可以用crypto-js來做。有人寫好的js檔案之類的,貼上過來就可以準備開發了。但是想起了我龍哥的話,寫程式碼要優雅。正好也一直關注著微信小程式生態,知道可以使用npm了。正好有crypto-js的包,說幹就幹。

首先在小程式的專案目錄裡面  執行 npm init --yes, 生成一個package.json。還有官方文件的建議,下載npm包的時候 執行  npm install --production。

npm install --production --save crypto-js。

這樣我們們想要的就都有了,主要說一下aes加密,啦啦啦。

首先先引入嘛

送給寫小程式的你。

/** * aes加密 * {加密欄位} word * {祕鑰} keyStr */
function encrypt_aes(word, keyStr) {    
    let key = CryptoJS.enc.Utf8.parse(keyStr);    
    let srcs = CryptoJS.enc.Utf8.parse(word);    
    let encrypted = CryptoJS.AES.encrypt(srcs, key, {        
        mode: CryptoJS.mode.ECB,        
        padding: CryptoJS.pad.Pkcs7    
    });    
    let result = encrypted.toString();    
    console.log("aes加密欄位", result)    
    return result;
}
/** * aes解密 * {加密欄位} word * {祕鑰} keyStr */
function decrypt_aes(word, keyStr) {    
    let key = CryptoJS.enc.Utf8.parse(keyStr);    
    let decrypt = CryptoJS.AES.decrypt(word, key, {        
        mode: CryptoJS.mode.ECB,        
        padding: CryptoJS.pad.Pkcs7    
    });    
    let result = CryptoJS.enc.Utf8.stringify(decrypt).toString();    
    console.log("aes解密欄位", result)    
    return result;
}複製程式碼

效果如圖:

送給寫小程式的你。

這樣就可以實現 前端aes加密了。可以送我一朵小發發~

---------------------------------------------------------------------


一步步記錄自己的踩坑歷程~我要做到我技術不是最好的,但我給你總結的小程式的東西是最簡單粗暴的哈哈哈




送給寫小程式的你。


相關文章