送給寫小程序的你。

 

聲明:本人也是菜鳥一隻,寫的很差的地方,大佬們指點指點。javascript

歡迎來點點個人博客html

微信小程序商城,持續更新。(已經跳槽了,可是仍是小程序相關的項目/斜眼)前端

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

因而就開始了我從零開始寫微信小程序商城之路。android

微信小程序的官方文檔什麼的我就不說了,那是確定要看的。說說我這幾天開始寫我遇到的問題。但願對將要寫小程序的你能有一絲絲幫助,由於本人也很菜。ios

一、微信小程序之rpx

在微信官方的文檔中,咱們看到這樣一句話:git

在 iPhone 6 上,屏幕寬度爲 375px,共有 750 個物理像素,則 750rpx = 375px = 750 物理像素,1rpx = 0.5px = 1 物理像素。開發微信小程序時設計師能夠用 iPhone 6 做爲視覺稿的標準。也就是說,設計師在設計小程序時,能夠這樣作:es6

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

其實總的來講就是,你跟UI小姐姐說一聲,而後就能夠很爽的寫樣式了。github

二、微信小程序之容器視圖

  • 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>web

三、微信小程序之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

四、微信小程序之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'
})
}

五、微信小程序之禁止頁面下拉

有的時候你會遇到不讓頁面下拉,若是你覺得我說的是下拉刷新的api的話那就圖樣了。就是不讓你下滑的時候出來那個白條。直接上代碼了:

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

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

最新解決方法,在app。json 裏面增長一條這個屬性,就能夠禁止滾動。

六、微信小程序之頁面深度

在測試本身的項目的時候,發現明明邏輯沒問題,語法也沒問題。忽然想起來小程序的頁面棧是五個,因而特別中二的數了一下本身的頁面跳轉哈哈... 才發現當時本身的理解是錯誤的,剛開始不細心看文檔,我覺得這五個頁面是超過五個會把新的加進頁面棧,第一個打開的銷燬。我就無腦用wx.navigateTo,遇到這個問題後用了 wx.redirectTo就解決了。可是誰讓我好學呢,因而發現一個大神寫的特別完美的理解小程序頁面跳轉的原理。

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

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

七、微信小程序之上拉加載

我如今公司的項目作的是電商的小程序,下拉刷新,官網寫的很明確不能與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的狀態來延時請求接口。實現效果以下圖:
複製代碼

這就是我用上拉加載的實踐,但願有大神能提出更好的建議。

八、微信小程序之數據交互

說到這裏順便把個人一些關於數據交互的一些經驗分享一下

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)
      }
  });
複製代碼
把接口暴露出去在其餘頁面調用

但願有大神能幫忙一下小程序的組件化最佳實踐~

九、微信小程序之Android請求失敗的坑

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

這個錯還讓我跟運維的大哥撕了半天哈哈, 首先出現這個錯,兄弟這個鍋完徹底全就能甩給運維的大哥,不留任何餘地。 而後能夠幫大哥提供一些資料,一步步排查,先查你項目綁定域名:

一、https證書問題 :ssl證書配置須要使用pem,不使用crt, ,

二、服務器端的版本信息:TLS版本的問題,該問題在微信小程序官方文檔中已經說起到,服務器TLS版本必須支持 1.2 (啓用1.2,禁用1.1和1.0等低版本),

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

十、微信小程序之地址頁面三級聯動

說道這個問題,現給你們貼一個地址,很是感謝大神的開源: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~

十一、微信小程序之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;哈哈哈
複製代碼

十二、微信小程序之Ios環境下mp4播放問題

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

1三、微信小程序之微信支付的坑

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

這個api裏面的全部數據都是後端返給你的,不要接受他的甩鍋哈哈。

還有就是必定要讓後端好好看微信支付的文檔,通常公司開發商城都是服務商版的支付服務,這裏就是我和後端大哥的甩鍋之路,他沒有綁定我得小程序appid,而後各類說調不通。。。

去這裏配置好,前端只須要調API傳值就好

1四、微信小程序之圖片上傳

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

老規矩,直接上代碼了。

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
          }
        })
    }
這個是多個圖片上傳的方法,單個圖片上傳的話,把循環去掉就好。主要是由於微信官方默認的就是一次上傳一張圖片這個很蛋疼。只能這麼搞了。。。
複製代碼

1五、微信小程序之電商購物車邏輯

接着再給你們分享一個關於小程序購物車全選的邏輯處理,這個仍是要感謝個人老妹教導我,一個開發人員作東西必定要嚴謹,無論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,再賦值。

通過這幾步操做以後就解決了全選這方面的全部邏輯,以爲有用的小夥伴,記得評論,關注喲~

1六、微信小程序之使用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 }) },
複製代碼

這樣就實現了,對選項卡的優化,若是接口數據變多了的話,會從新賦值。 雖然是本身給本身加戲,但這是也是個人一種工做態度,學習了新東西,還讓優化了項目。

1七、小程序之全局變量緩存的問題

這個問題的出現是由於,在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);
        }
    }
複製代碼

1八、小程序之微信支付的深坑

事情是這樣的,由於公司主體變動,避稅之類的事。咱們公司的小程序,須要從新換綁微信支付,在財務給咱們申請號商戶號以後,咱們排期半夜來切環境。 我記得是一個週四的晚上,十二點開始切環境,而後 大概後端代碼數據庫都準備好以後,咱們從新綁定微信支付,覺得大功告成。週五還能彈性一上午美滋滋~

沒想到 剛交個測試,說微信支付不能用,提示咱們沒有受權。wtf,剛綁定好的你這樣提示,不合適吧。按照報錯一查,我去小程序 社區裏一看。

你敢信,微信開放平臺的商戶號和公衆號商戶號,是兩回事。 小程序之支持公衆號的商戶號,可是你在開放平臺綁定小程序微信支付的時候,官方給你的提示是 綁定成功~。

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

血的教訓呀!!!

1九、小程序之登錄改版

https://juejin.cn/post/6844903614792597518

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

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會自動放到小程序的頭部做爲標題;

2一、小程序之調用上個頁面方法

由於,如今的項目是小程序嵌套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的路由。是否是很方便呢。

2二、小程序之使用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加密了。能夠送我一朵小發發~

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


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




相關文章
相關標籤/搜索