小程序的一些小知識總結

1. 小程序不少方法都是異步的緣由(官方說法:天生異步)

剛接觸小程序的時候,發現不少微信提供的api都是異步的,如路由跳轉,設置和讀取緩存,還有獲取節點信息等微信的api,都是異步的,須要傳入回調函數才能得到結果,在咱們正常的前端開發中,這些都不是異步的,當時很奇怪爲何是這樣的,最近看了微信的一個開發教程以後,總算是明白了。微信小程序開發教程前端

小程序的底層架構是雙線程模式,邏輯層和渲染層是分開的兩個線程,渲染層指的就是渲染wxml和wxss,邏輯層指的是執行js文件,兩個線程分開運行,經過微信客戶端進行通訊,調用微信的api的時候其實就是執行js的線程和微信客戶端通訊。
下圖是微信官方文檔裏渲染頁面的一個流程圖
clipboard.pnggit

注意事項:
上述說了,小程序的渲染層和邏輯層是分開的兩個線程,執行js邏輯的只有一個線程,因此在js裏聲明瞭的函數,只要有調用,就算頁面卸載了,最終都會執行,因此要注意的是,一些interval,或者一些註冊的其餘函數,若是不想在頁面離開後繼續執行的話,在頁面卸載的時候要註銷掉。github

2. 發佈和訂閱模式

先補充一個知識點:在小程序的appjs的onLaunch裏,給全局變量wx添加的屬性,是全局有效的,能在其餘頁面中調用,好比:小程序

onLaunch: function () {
    wx.aaa = '123456'; 
    wx.bbb = function () { console.log('541521') }
}


onLoad: function () {
    console.log(wx.aaa);
    wx.bbb();
}

以前對發佈和訂閱一直沒什麼概念,可是多學點東西總沒壞處,近期本身花了點時間專門看了一下,大概明白了一點。微信小程序

訂閱:訂閱就是在某個地方註冊一個自定義的事件,供其餘地方調用
發佈:觸發已經訂閱的函數api

下面是我寫的一個方法,可能會有一些bug,可是目前沒有發現,要是有問題的話歡迎交流一下數組

const myEvent = (function() {
  // 聲明方法
  var pub, sub, remove;

  // 訂閱緩存記錄
  var subCache = {};
  // 發佈緩存記錄
  var pubCache = {};
  // 參數緩存
  var paramCache = {};

  // 訂閱事件
  sub = function(key, fn) {
    if (!subCache[key]) {
      subCache[key] = [];
    }
    // 添加到訂閱緩存中

    subCache[key].push(fn);
    // 若是有發佈記錄,則直接執行函數
    if (pubCache[key]) {
      if (paramCache[key]) {
        fn.apply(null, paramCache[key]);
      } else {
        fn.apply(null);
      }
      // 若是把參數和發佈緩存清除的話,就是隻容許單次執行
      // paramCache[key] = [];
      // pubCache[key] = undefined;
    }
  };
  pub = function() {
    var key = Array.prototype.shift.call(arguments);
    var fns = subCache[key];
    var args = Array.prototype.slice.call(arguments, 0);
    pubCache[key] = true;
    paramCache[key] = args;
    if (!fns || fns.length === 0) {
      return;
    }
    // 有訂閱記錄,則直接執行
    for (let fn of fns) {
      fn.apply(null, args);
    }
  };
  remove = function(key, fn) {
    if (subCache[key]) {
      if (fn) {
        for(let i = 0, len = subCache[key].length; i < len; i++) {
          if (fn == subCache[key][i]) {
            subCache[key].splice(i, 1);
            break;
          }
        }
      } else {
        // 把全部的緩存所有清除
        subCache[key] = undefined;
        pubCache[key] = undefined;
        paramCache[key] = undefined;
      }
    }
  };
  return {
    pub: pub,
    sub: sub,
    remove: remove
  };
})();

module.exports = myEvent;

使用方法以下:
在appjs裏引入MyEvent,並掛載在wx對象上緩存

App({
  onLaunch: function () {
    const MyEvent = require('myEvent的路徑');
    wx.myEvent = MyEvent;
  }
})

在其中頁面頁面1的onShow裏訂閱test1事件,發佈test2事件微信

onLoad: function(){
    wx.myEvent.sub('test1', function () {
        console.log('test1');
    });
},
onShow: function () {
    wx.myEvent.pub('test2', 'test2' + new Date().getTime());
}

在頁面2的onLoad事件裏,發佈test1事件,訂閱test2事件閉包

onLoad: function(options) {
    wx.myEvent.pub('test1');
    wx.myEvent.sub('test2', function(a){
      console.log(a);
    });
}

一. 在頁面1的時候,執行了訂閱test1事件,發佈了test2事件,可是test1沒有發佈,訂閱的事件不會執行,test2事件沒有訂閱,也不會執行。

二. 從頁面1跳轉到頁面2,發佈了test1事件,直接執行以前已經註冊好的test1事件,訂閱test2事件,由於有test2的發佈事件,訂閱以後直接執行,結果是打印一次test1,打印一次test2。

三. 從頁面2返回到頁面1,執行onShow事件,再次發佈test2事件,打印一次test2

四. 從頁面1到頁面2,發佈了test1事件,事件test2重複訂閱了,訂閱了兩次,打印一次test1。

五. 從頁面2返回頁面1,發佈test2,由於test2事件訂閱了兩次,因此打印了兩次test2,因此要注意在不須要的地方把事件註銷。

在頁面2的onUnload事件裏把事件test2註銷掉,在從頁面2回到頁面1的時候,事件test2已經註銷了,不會再執行。

onUnload: function() {
    wx.myEvent.remove('test2');
}

原理和用法說明:
原理:
全局只有一個wx對象,將myEvent掛載在wx上,因此全局也只有一個wx.myEvent對象,myEvent裏用到了閉包,訂閱的函數和參數都有保存在內存裏,因此能實現訂閱和發佈的功能。
目前事件訂閱是用的數組存儲,可實現同一個事件訂閱屢次,若是不須要的話可自行修改爲只能訂閱一次的方法。
用法:
通常用於跨頁面的操做,好比在某個頁面訂閱某個事件,在另外一份頁面執行了某項操做以後,發佈該事件,會直接執行訂閱的事件,實現頁面間的一些數據傳遞。
還有也可用於異步請求,先訂閱某個事件,異步請求數據,請求數據回來以後,再發布。

使用例子
在使用發佈和訂閱的方法以前,好比新增地址,從列表頁面跳轉到新增頁面,在新增頁面新增地址成功以後,將新增的地址放到緩存,接着返回列表頁面,使用navigateBack,在列表頁面的onShow裏檢測是否有緩存,有緩存,則從新加載地址列表
使用發佈訂閱的方法以後,能夠在列表頁面的onLoad裏訂閱新增地址的事件,在新增地址頁面,新增以後,發佈一個新增地址事件,列表頁面監聽到有新增地址事件,則新增一個地址,瞬間感受高大上了

3. 推薦幾個小程序的組件庫

用別人的源碼能夠加快開發速度,並且能夠學習別人的源碼
We UI WeUI 是一套同微信原生視覺體驗一致的基礎樣式庫,由微信官方設計團隊爲微信內網頁和微信小程序量身設計,令用戶的使用感知更加統一。這個是一個樣式庫,只提供樣式。
vant-weapp 這個是一個組件庫,裏面封裝了一些經常使用的組件,是有讚的vant組件庫的小程序版本,我的感受用起來仍是挺好用的。

待補充......

相關文章
相關標籤/搜索