人人妻人人澡人人爽人人精品97,色狠狠色狠狠综合天天,国产一区二区三区在线播放,久久久久久AV无码免费网站

十年技術深耕細作

為您提供各行業互聯網私人定制開發解決方案

免費咨詢熱線15890197308
新聞資訊
把握先機贏得挑戰與世界同步
首頁 新聞中心 小程序開發

微信小程序從入門到精通(二) 小程序的能力

來源:超達科技 發布時間:2018-03-29瀏覽:3835次

微信小程序從入門到精通(二)小程序的能力前言上一篇blog介紹了小程序的一些基礎概念和代碼構成以及主要的幾個文件類型(微信小程序從入門到精通(一)基礎知識與代碼構成),那么本篇blog就繼續圍繞官方的簡易教程以及QuickStart項目來繼續研究一下小程序如何工作。小程序能力上次我們具體了解小程序的代碼構成以及四個重要的文件類型(wxml、wxss、js和app.json),那么接下來就看看小程序的整體工作運行流程,首先從啟動開始。小程序的啟動首先來看一下小程序啟動后首先會發生什么事情,引用官方文檔的說明:小程序啟...

微信小程序從入門到精通(二) 小程序的能力

前言

上一篇blog介紹了小程序的一些基礎概念和代碼構成以及主要的幾個文件類型( 微信小程序從入門到精通(一) 基礎知識與代碼構成),那么本篇blog就繼續圍繞官方的簡易教程以及QuickStart項目來繼續研究一下小程序如何工作。

小程序能力

上次我們具體了解小程序的代碼構成以及四個重要的文件類型(wxml、wxss、js和app.json),那么接下來就看看小程序的整體工作運行流程,首先從啟動開始。

小程序的啟動

首先來看一下小程序啟動后首先會發生什么事情,引用官方文檔的說明:

小程序啟動之后,在 app.js 定義的 App 實例的 onLaunch 回調會被執行。

App({
  onLaunch: function () {
    // 小程序啟動之后 觸發
  }
})12345

如上所示,這里又提到了一個文件——app.js,之前我們了解了app.json(全局配置,包含頁面路徑等)和app.wxss(全局樣式),那么同理app.js也是一個用于描述公共邏輯代碼的文件,是小程序中必須的兩個主配置文件之一(app.json和app.js):
這里寫圖片描述
這里暫且只需要明確一個小程序的主體必定是有3個文件構成的,分別是app.js(必須)、app.json(必須)和app.wxss(可選),明確了這一點之后我們繼續來看剛才官方文檔中提到的App實例,也就是在上面的代碼中看到的App{()},這里就牽扯到了另一個重要概念——注冊程序,屬于邏輯層的操作(App Service),官方文檔中有這樣一句話:

增加 App 和 Page 方法,進行程序和頁面的注冊。

如上所示,Page方法我們之前已經見過了,WXML 中的動態數據均來自對應 Page的data,用于注冊一個頁面,關于Page我們后面再說,但我們需要知道App和Page方法是邏輯層(App Service)最核心的兩個方法,接下來我們首先具體研究一下App方法,引用官方文檔的概述:

App() 函數用來注冊一個小程序。接受一個 object 參數,其指定小程序的生命周期函數等。

如上所示,object參數我們需要注意,在上面提到的onLaunch 回調就是這個object參數之一,上面示例代碼的注釋中說onLaunch會在小程序啟動后觸發,那么它會被調用幾次?依舊從官方文檔中來尋找答案,我們看一下App函數的object參數的所有屬性:

屬性類型描述觸發時機
onLaunchFunction生命周期函數–監聽小程序初始化當小程序初始化完成時,會觸發 onLaunch(全局只觸發一次)
onShowFunction生命周期函數–監聽小程序顯示當小程序啟動,或從后臺進入前臺顯示,會觸發 onShow
onHideFunction生命周期函數–監聽小程序隱藏當小程序從前臺進入后臺,會觸發 onHide
onErrorFunction錯誤監聽函數當小程序發生腳本錯誤,或者 api 調用失敗時,會觸發 onError 并帶上錯誤信息
其他Any
開發者可以添加任意的函數或數據到 Object 參數中,用 this 可以訪問

如上所示,可以看到onLaunch函數主要是做小程序的全局初始化工作,因為只會觸發一次,類似于在android開發中的application中設置一個靜態方法,在上面的表格中注意下描述列,onLaunch是一個生命周期函數,所以這里有必要再具體說明一下微信小程序中關于生命周期的一些概念,小程序的生命周期需要分為兩部分來說,分別是:

  1. 應用的生命周期

  2. 頁面的生命周期

這就不像在android中生命周期僅針對于界面(Activity、Fragment),在小程序的官方文檔中并沒有對生命周期做單獨介紹,而是以注冊程序注冊頁面這兩個標題來介紹了App()函數和Page()函數,然后分別在各自(App、Page)的object參數說明中以上面的表格的形式簡單標記出了哪些是生命周期函數,關于Page后面再說,先回歸正題,App()很明顯有3個生命周期函數,分別是:

  1. onLaunch

  2. onShow

  3. onHide

如上所示,除了onLaunch僅僅會執行一次之外,onShow和onHide都會根據生命周期的變化被多次執行,注意下在onShow觸發時機中提到了一個前臺后臺的概念,其實很簡單,跟android的那幾個容易混淆的onResume、onPause、onStop等等相比容易多了,引用官方文檔的原話:

當用戶點擊左上角關閉,或者按了設備 Home 鍵離開微信,小程序并沒有直接銷毀,而是進入了后臺;當再次進入微信或再次打開小程序,又會從后臺進入前臺。

就是這么簡單,那么小程序什么時候會被銷毀?官方文檔是這樣說的:

只有當小程序進入后臺一定時間,或者系統資源占用過高,才會被真正的銷毀。

先簡單了解一下,至于具體在什么場景銷毀,我們以后再做詳細說明,否則一次牽引出太多的點容易導致學習流程沒有主線,再次回到我們的主題onLaunch函數,QuickStart項目中的onLaunch內容略微有些復雜,我們簡單看一下:

//app.jsApp({
  onLaunch: function () {
    // 展示本地存儲能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)    // 登錄
    wx.login({
      success: res => {        // 發送 res.code 到后臺換取 openId, sessionKey, unionId
      }
    })    // 獲取用戶信息
    wx.getSetting({
      success: res => {        if (res.authSetting['scope.userInfo']) {          // 已經授權,可以直接調用 getUserInfo 獲取頭像昵稱,不會彈框
          wx.getUserInfo({
            success: res => {              // 可以將 res 發送給后臺解碼出 unionId
              this.globalData.userInfo = res.userInfo              // 由于 getUserInfo 是網絡請求,可能會在 Page.onLoad 之后才返回
              // 所以此處加入 callback 以防止這種情況
              if (this.userInfoReadyCallback) {                this.userInfoReadyCallback(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null
  }
})123456789101112131415161718192021222324252627282930313233343536373839

根據注釋我們可以大概看出來在onLaunch函數中做了幾件事情,我們以第一個“展示本地存儲能力”為例,詳細分析一下4~7行的代碼:

// 展示本地存儲能力var logs =wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)1234

如上所示,調用了wx.getStorageSyncwx.setStorageSync這2個API,這就是小程序為我們提供的本地存儲API,早期的移動web開發中本地存儲只能用cookie的方式解決,但是cookie大小限制在4K,而且某些瀏覽器還存在cookie個數限制,而后隨著H5的發展本地存儲可以通過localStorage這個東東解決,但也僅是IE8以后才能支持,大小有5M,這就解決了很大一部分的存儲容量問題,而我們微信小程序的官方文檔中說了:

同一個微信用戶,同一個小程序 storage 上限為 10MB。

OK,本地緩存容量上又進一步提升了,現在看一下wx.getStorageSync和wx.setStorageSync的說明以及用法:

  1. wx.setStorageSync(KEY,DATA)  
    將 data 存儲在本地緩存中指定的 key 中,會覆蓋掉原來該 key 對應的內容,這是一個同步接口。

  2. wx.getStorageSync(KEY)
    從本地緩存中同步獲取指定 key 對應的內容。

如上所示,使用方法很簡單,同android的SharedPreferences用法類似,都是以key/value的形式去存取數據,注意這兩個是同步接口,API中也有兩個異步的版本(wx.setStorage和wx.getStorage),這兩個異步接口參數相對就多一些了,以后再說,回到代碼中來,現在看這3行代碼就比較清晰了,首先通過獲取本地緩存中key為logs所對應的值,如果為0或者null(首次啟動)就返回一個空數組,然后在這個空數組中追加一個元素(當前時間),最后將當前時間存入本地緩存,key為logs。說白了這就是記錄一個啟動日志,首次啟動會創建一個新數組,之后每次啟動都會給這個數組追加當前時間,所以我們在模擬器中的index頁面點擊頭像后跳轉到logs頁面看到的時間列表就是從緩存讀取的:
這里寫圖片描述

關于onLaunch函數還有一點需要說的就是它默認是帶有一個參數的,包括onShow方法:

App({
  onLaunch: function(options) {
    // Do something initial when launch.
  },
  onShow: function(options) {
      // Do something when show.
  },
  onHide: function() {
      // Do something when hide.
  },
  onError: function(msg) {
    console.log(msg)
  },
  globalData: 'I am global data'})123456789101112131415

如上所示,那么這個options參數都包含哪些屬性呢?官方文檔列出了7個屬性(path、query、scene、shareTicket、referrerInfo、referrerInfo.appId、referrerInfo.extraData),下面只列舉2個先簡單了解下,我們在onLaunch函數中打印一下options的path和sence屬性:
這里寫圖片描述
這里寫圖片描述

path是打開小程序的路徑,scene是打開小程序的場景值,關于場景值的概念以后再說,此處簡單了解一下即可,接下來要說一個比較重要的函數getApp(),它可以用來獲取到小程序實例,例如獲取全局變量globalData:

// other.jsvar appInstance = getApp()
console.log(appInstance.globalData) // I am global data123

如上所示,關于小程序啟動相關的內容先說這么多,接下來看一下頁面相關的內容。

程序與頁面

接下來要說的就是本篇blog的重點內容了,注冊頁面,也就是關于Page函數。上一篇blog我們簡單介紹了一部分關于Page的內容,下面看一下官方文檔簡易教程中對Page的概述和一段示例代碼:

Page 是一個頁面構造器,這個構造器就生成了一個頁面。在生成頁面的時候,小程序框架會把 data 數據和 index.wxml 一起渲染出最終的結構,于是就得到了你看到的小程序的樣子。在渲染完界面之后,頁面實例就會收到一個 onLoad 的回調,你可以在這個回調處理你的邏輯。

Page({
  data: { // 參與頁面渲染的數據
    logs: []
  },
  onLoad: function () {
    // 頁面渲染后 執行
  }
})12345678

如上所示,之所以說Page重要,是因為它的作用的構造頁面,而我們的小程序就是通過一個個頁面組成的,Page函數的2個核心點分別是dataonLoad回調,data負責提供數據,onLoad則是處理頁面渲染后的邏輯。接下來我們就具體看一下Page函數,我們在IDE中新建一個js文件后寫一個字母P首先看到的就是Page函數的自動補全提示:
這里寫圖片描述

如上圖,緊接著會自動生成一個完整的Page函數模板,代碼如下:

Page({  /**
   * 頁面的初始數據
   */
  data: {

  },  /**
   * 生命周期函數--監聽頁面加載
   */
  onLoad: function (options) {

  },  /**
   * 生命周期函數--監聽頁面初次渲染完成
   */
  onReady: function () {

  },  /**
   * 生命周期函數--監聽頁面顯示
   */
  onShow: function () {

  },  /**
   * 生命周期函數--監聽頁面隱藏
   */
  onHide: function () {

  },  /**
   * 生命周期函數--監聽頁面卸載
   */
  onUnload: function () {

  },  /**
   * 頁面相關事件處理函數--監聽用戶下拉動作
   */
  onPullDownRefresh: function () {

  },  /**
   * 頁面上拉觸底事件的處理函數
   */
  onReachBottom: function () {

  },  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

注釋也都比較清晰,可以看到Page函數有5個生命周期函數(onLoad、onReady、onShow、onHide、onUnload),相比較App函數(onLaunch、onShow、onHide)多出了2個,同樣的Page函數也支持我們自定義函數或者數據,就如同上一篇blog中寫的那個clickMe函數,下面我們按順序依次了解一下,首先是data,data在官方文檔中的定義是初始化數據,文檔中是這樣描述的:

初始化數據將作為頁面的第一次渲染。data 將會以 JSON 的形式由邏輯層傳至渲染層,所以其數據必須是可以轉成 JSON 的格式:字符串,數字,布爾值,對象,數組。

如上所示,這里我們注意兩點,分別是第一次渲染JSON格式。第一次渲染的意思就是在onLoad函數被調用之前的頁面渲染,而JSON格式則是定死了data中的數據類型只能是以下幾種(String,Number,Boolean,Object,Array),下面看一下QuickStart項目中Page函數的data部分:

Page({  data: {    motto: 'Hello World',    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')
  }
})12345678

如上所示,這里定義的初始化數據比較簡單,字符串motto直接通過wxml中的{{motto}}渲染在頁面并顯示,Object類型的用戶信息(userInfo),具體講是一個JSON對象,這里初始化為空,因為會在onLoad函數中賦值,Boolean類型的是否存在用戶信息標志(hasUserInfo)以及Boolean類型的“判斷小程序的API,回調,參數,組件等是否在當前版本可用”的標志。看完了data接下來看一下更重要的生命周期函數,首先是最重要的onLoad函數,它與App()中的onLaunch函數相對應,后者是小程序啟動后全局觸發一次,前者則是一個頁面只會調用一次,所以這個onLoad也就相當于android中Activity的onCreate,依舊看一下QuickStart項目中的onLoad函數,由于index.js中的onLoad略微復雜,我們先以log.js中的onLoad函數為例:

Page({
  data: {
    logs: []
  },
  onLoad: function () {
    this.setData({
      logs: (wx.getStorageSync('logs') || []).map(log => {        return util.formatTime(new Date(log))
      })
    })
  }
})123456789101112

這個例子就很好,用到了我們上面提到過的本地緩存(wx.getStorageSync)和data,可以看到data中定義了一個空數組,然后在onLoad函數中做了賦值操作(setData),所以這里我們可以再仔細體會一遍data和onLoad各自的作用和關系。說到了setData,下面就詳細說明一下這個函數Page.prototype.setData(),首先看一下官方文檔中的概述:

setData 函數用于將數據從邏輯層發送到視圖層(異步),同時改變對應的 this.data 的值(同步)。

如上所示,可以看到setData函數做了兩件事情,首先是把數據以異步形式發送到視圖層,也就是說可以理解為對頁面進行的第二次渲染,然后以同步形式改變了this.data的值,也就是在這里同步修改了初始化數據,這里再強調一點,同App()函數一樣,Page()函數的參數也支持任意類型的自定義函數或數據,同樣是通過this調用,下面看一下官方文檔給出的幾個小例子:

//index.jsPage({
  data: {
    text: 'init data',
    num: 0,
    array: [{text: 'init data'}],
    object: {
      text: 'init data'
    }
  },
  changeText: function() {
    // this.data.text = 'changed data'  // bad, it can not work
    this.setData({
      text: 'changed data'
    })
  },
  changeNum: function() {
    this.data.num = 1
    this.setData({
      num: this.data.num
    })
  },
  changeItemInArray: function() {
    // you can use this way to modify a danamic data path
    this.setData({      'array[0].text':'changed data'
    })
  },
  changeItemInObject: function(){
    this.setData({      'object.text': 'changed data'
    });
  },
  addNewField: function() {
    this.setData({      'newField.text': 'new data'
    })
  }
})123456789101112131415161718192021222324252627282930313233343536373839

注意下第12行的注釋代碼,不能直接通過this.data.key = “xxx”去改變data中的數據,必須要通過setData方法才能改變。在上面的例子中我們依次列舉了修改以下幾種類型的數據:

  1. 字符串 line11~16

  2. 數字 line17~22

  3. 數組 line23~28

  4. 對象 line29~38

如上所示,需要注意的是再修改data為Object類型的數據時,setData中參數對象的key必須是字符串形式,例如'object.text': 'changed data',說了這么多關于Page的生命周期函數也只講了1個——onLoad,關于剩下的幾個非重點函數(onShow、onReady、onHide和onUnload)以后再說,否則會導致篇幅過長。跳過這幾個生命周期函數,那我們的Page函數還剩下幾個事件處理函數,我們以下拉刷新(onPullDownRefresh)上拉觸底(onReachBottom)為例詳細說明一下。依舊先看一下官方文檔對這兩個函數的詳細說明:
這里寫圖片描述

如上所示,首先是下拉刷新,很簡單,監聽用戶下拉刷新動作,上一篇blog也提到了需要在app.json中配置開啟下拉刷新后才行,看以一個簡單的例子:

Page({  onPullDownRefresh:function(){
    wx.showToast({
      title: '執行了下拉刷新動作~',
      icon: 'none',
      duration: 2000
    })
  }
})123456789

這里又用到了一個簡單的交互反饋API——顯示消息提示框,跟android中的吐司基本一樣,用法也很簡單,title是提示內容,duration是延遲時間(單位毫秒),icon是圖標,可以設置為“success”、“loading”和“none”,下面看一下下拉的效果圖:
這里寫圖片描述

如上所示,而上拉觸底則需要在scroll-view組件中去滑動才能觸發諸如滾動條滾動觸底觸頂等事件,牽扯到組件的問題我們后面再說。

總結

本篇blog重點介紹了注冊程序(App函數)和注冊頁面(Page函數)的相關用法以及setData函數的用法,主要還停留在基礎理性的部分,等后面學習了組件之后就可以嘗試做一些東西了,由于以前js基礎不是特別好所以在學習過程中會遇到各種各樣的js語法糖,那就開開心心的當補習js基礎知識好了!先到這里吧,The End。