微信小程序開發(fā)入門教程

作者也是剛開始接觸小程序開發(fā)塘安,不足之處請(qǐng)指正卧斟。

目錄

先看工程目錄殴边,index、logs唆涝、mine找都、wallet這幾個(gè)文件夾可以看做一個(gè)個(gè)頁(yè)面,每個(gè)文件夾(頁(yè)面)里有四個(gè)文件:.js .json .wxml .wxss

.js文件就是JavaScript廊酣,寫邏輯相關(guān)的代碼
.json文件做一些固定的配置
.wxml類似于html寫控件
.wxss類似于css 寫控件的樣式

具體來看
創(chuàng)建一個(gè)小程序項(xiàng)目會(huì)默認(rèn)有app.js能耻,app.json,app.wxss這三個(gè)文件作用于是整個(gè)小程序亡驰,而每個(gè)頁(yè)面里的這幾個(gè)文件的作用域是當(dāng)前頁(yè)面晓猛。

先來看官方默認(rèn)創(chuàng)建的代碼

//app.js
App({
  onLaunch: function () {
    // 展示本地存儲(chǔ)能力
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs', logs)

    // 登錄
    wx.login({
      success: res => {
        // 發(fā)送 res.code 到后臺(tái)換取 openId, sessionKey, unionId
        console.log('code',res)
      }
    })
    // 獲取用戶信息
    wx.getSetting({
      success: res => {
        console.log('setting',res.authSetting)
        if (res.authSetting['scope.userInfo']) {
          // 已經(jīng)授權(quán),可以直接調(diào)用 getUserInfo 獲取頭像昵稱凡辱,不會(huì)彈框
          wx.getUserInfo({
            success: res => {
              // 可以將 res 發(fā)送給后臺(tái)解碼出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是網(wǎng)絡(luò)請(qǐng)求戒职,可能會(huì)在 Page.onLoad 之后才返回
              // 所以此處加入 callback 以防止這種情況
              if (this.userInfoReadyCallbacks) {
                this.userInfoReadyCallbacks(res)
              }
            }
          })
        }
      }
    })
  },
  globalData: {
    userInfo: null
  }
})

onLaunch函數(shù)是小程序生命周期函數(shù),監(jiān)聽小程序初始化透乾。即小程序入口洪燥,通過查閱官方文檔可以看到此函數(shù)的解釋。


屏幕快照 2019-07-16 下午3.42.44.png

下面來分析 var logs = wx.getStorageSync('logs') || []乳乌,wx.調(diào)用的wx.getStorageSync一看就是微信官方API捧韵,這行代碼是同步獲取key為'logs'的緩存,且logs變量類型為數(shù)組汉操。通過查閱官方API可以看到此函數(shù)的定義再来,同步獲取緩存也就是會(huì)阻塞當(dāng)前線程的意思嘍,即獲取完這個(gè)數(shù)組才會(huì)繼續(xù)執(zhí)行代碼。


API

logs.unshift(Date.now())又是啥意思呢芒篷,查詢微信官方API發(fā)現(xiàn)unshift方法是ES5標(biāo)準(zhǔn)里的搜变,意思是在數(shù)組的最前面插入一個(gè)元素,這里是插入了當(dāng)前時(shí)間戳针炉。

wx.setStorageSync('logs', logs)從字面看就是同步保存這個(gè)被修改的數(shù)組到緩存中挠他。

    // 登錄
    wx.login({
      success: res => {
        // 發(fā)送 res.code 到后臺(tái)換取 openId, sessionKey, unionId
        console.log('code',res)
      }
    })
屏幕快照 2019-07-16 下午3.47.09.png

這個(gè)wx.login是什么意思,wx.開頭即微信提供的API篡帕,意思是調(diào)用了login接口獲取登錄憑證(code)绩社,調(diào)用成功即success會(huì)返回code,然后向我們自己的服務(wù)器請(qǐng)求換取openId, sessionKey, unionId這些信息赂苗,來進(jìn)行登錄操作。

    // 獲取用戶信息
    wx.getSetting({
      success: res => {
        console.log('setting',res.authSetting)
        if (res.authSetting['scope.userInfo']) {
          // 已經(jīng)授權(quán)贮尉,可以直接調(diào)用 getUserInfo 獲取頭像昵稱拌滋,不會(huì)彈框
          wx.getUserInfo({
            success: res => {
              // 可以將 res 發(fā)送給后臺(tái)解碼出 unionId
              this.globalData.userInfo = res.userInfo

              // 由于 getUserInfo 是網(wǎng)絡(luò)請(qǐng)求,可能會(huì)在 Page.onLoad 之后才返回
              // 所以此處加入 callback 以防止這種情況
              if (this.userInfoReadyCallbacks) {
                this.userInfoReadyCallbacks(res)
              }
            }
          })
        }
      }
    })

wx.getSetting用來獲取小程序已經(jīng)向用戶請(qǐng)求過的權(quán)限猜谚,返回形式是一個(gè)字典(key:value)形式败砂,其中'scope.userInfo'就是獲取用戶信息的key,如果這項(xiàng)為true就是獲取到用戶信息的意思。


屏幕快照 2019-07-16 下午3.52.14.png

wx.getUserInfo用來獲取用戶信息魏铅,success就會(huì)返回用戶信息

this.globalData.userInfo = res.userInfo昌犹,this類似于iOS開發(fā)中的self,globalData是自定義的一個(gè)全局變量览芳,內(nèi)部數(shù)據(jù)結(jié)構(gòu)是有一個(gè)userInfo斜姥,用來全局保存用戶信息。

this.userInfoReadyCallbacks又是個(gè)什么呢沧竟,類似于iOS開發(fā)中的block(閉包),函數(shù)名隨便取铸敏,我就在后面加了個(gè)s, 用來異步反向傳值,因?yàn)閣x.getUserInfo這個(gè)接口是異步獲取的悟泵,有可能會(huì)在index的js里的onLoad方法之后返回杈笔,如果index頁(yè)面調(diào)用了userInfoReadyCallbacks來接收userInfo數(shù)據(jù),則app.js里會(huì)執(zhí)行this.userInfoReadyCallbacks(res)糕非,就可以異步給index頁(yè)面?zhèn)髦盗恕?/p>

//index.js
      app.userInfoReadyCallbacks = res => {
        if (res.userInfo) {
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      }

下面來看index.js文件

//index.js
//獲取應(yīng)用實(shí)例
const app = getApp()

Page({
  data: {
    motto: '尬先生尬先生尬先生尬先生尬先生尬先生尬先生尬先生',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')//固定寫法 通過button獲取用戶信息只能這么寫
  },
  //事件處理函數(shù)
  bindViewTap: function () {//點(diǎn)擊頭像跳轉(zhuǎn)logs頁(yè)面
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    } else if (this.data.canIUse) {
      // 由于 getUserInfo 是網(wǎng)絡(luò)請(qǐng)求蒙具,可能會(huì)在 Page.onLoad 之后才返回
      // 所以此處加入 callback 以防止這種情況
      app.userInfoReadyCallbacks = res => {
        if (res.userInfo) {
          this.setData({
            userInfo: res.userInfo,
            hasUserInfo: true
          })
        }
      }
    } else {
      // 在沒有 open-type=getUserInfo 版本的兼容處理
      wx.getUserInfo({
        success: res => {
          if (res.userInfo) {
            app.globalData.userInfo = res.userInfo
            this.setData({
              userInfo: res.userInfo,
              hasUserInfo: true
            })
          }
        }
      })
    }
  },

  getUserInfoClick: function (e) {//點(diǎn)擊了拒絕或同意后會(huì)回調(diào)
    if (e.detail.userInfo) {
      app.globalData.userInfo = e.detail.userInfo
      this.setData({
        userInfo: e.detail.userInfo,
        hasUserInfo: true
      })
    }
  }
})

const app = getApp()獲取應(yīng)用實(shí)例,這樣就可以使用全局變量了朽肥。

 data: {
    motto: '尬先生尬先生尬先生尬先生尬先生尬先生尬先生尬先生',
    userInfo: {},
    hasUserInfo: false,
    canIUse: wx.canIUse('button.open-type.getUserInfo')//固定寫法 通過button獲取用戶信息只能這么寫
  },

定義了一個(gè)名為data的數(shù)據(jù)結(jié)構(gòu)禁筏,有四個(gè)元素motoo是一個(gè)字符串,userInfo用戶信息鞠呈,hasUserInfo是否獲取到了用戶信息bool類型融师,canIUse判斷小程序的API,回調(diào)蚁吝,參數(shù)旱爆,組件等是否在當(dāng)前版本可用舀射,當(dāng)前是判斷button里獲取用戶信息在當(dāng)前版本是否可用,'button.open-type.getUserInfo'就是通過button獲取用戶信息的固定寫法怀伦。


屏幕快照 2019-07-16 下午4.50.48.png

bindViewTap: function () 是在index.wxml里綁定的頭像image點(diǎn)擊事件脆烟,即登錄以后點(diǎn)擊頭像進(jìn)行后續(xù)操作。

    wx.navigateTo({
      url: '../logs/logs'
    })

wx.navigateTo保留當(dāng)前頁(yè)面房待,跳轉(zhuǎn)到應(yīng)用內(nèi)的某個(gè)頁(yè)面邢羔,url: '../logs/logs'即跳轉(zhuǎn)到logs頁(yè)面

  if (app.globalData.userInfo) {
      this.setData({
        userInfo: app.globalData.userInfo,
        hasUserInfo: true
      })
    }

如果在app.js頁(yè)面獲取userInfo速度快于index.js的onLoad方法,走這里桑孩。 this.setData給data賦值的同時(shí)會(huì)主動(dòng)刷新index.wxml里的UI數(shù)據(jù)拜鹤。

  getUserInfoClick: function (e) {//點(diǎn)擊了拒絕或同意后會(huì)回調(diào)
    if (e.detail.userInfo) {
      app.globalData.userInfo = e.detail.userInfo
      this.setData({
        userInfo: e.detail.userInfo,
        hasUserInfo: true
      })
    }
  }

getUserInfoClick是在index.wxml里綁定的bindgetuserinfo="getUserInfoClick"即button的點(diǎn)擊以后彈出的權(quán)限授權(quán)框的點(diǎn)擊事件回調(diào)。

下面看下index.wxml文件

<!--index.wxml-->
<view class="container">
  <view class="userinfo">
    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfoClick"> 獲取頭像昵稱 </button>
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
</view>

<view>標(biāo)簽視圖容器流椒,class="container"敏簿,給這個(gè)view起個(gè)名字,方便在index.wxss文件里給這個(gè)標(biāo)簽設(shè)置樣式宣虾。

    <button wx:if="{{!hasUserInfo && canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfoClick"> 獲取頭像昵稱 </button>

<button>標(biāo)簽惯裕,wx:if="{{!hasUserInfo && canIUse}}"如果同時(shí)滿足!hasUserInfo && canIUse這兩個(gè)條件則繪制這個(gè)button,open-type="getUserInfo"意思是這個(gè)button點(diǎn)擊后用來請(qǐng)求用戶信息是固定寫法绣硝。bindgetuserinfo="getUserInfoClick"綁定一個(gè)名為getUserInfoClick的函數(shù)作為授權(quán)彈窗的回調(diào)方法蜻势。


屏幕快照 2019-07-16 下午5.07.10.png
    <block wx:else>
      <image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
      <text class="userinfo-nickname">{{userInfo.nickName}}</text>
    </block>

<block>如果要一次性判斷多個(gè)組件標(biāo)簽,可以使用一個(gè) <block/> 標(biāo)簽將多個(gè)組件包裝起來鹉胖,這里包裝了一個(gè)<image>和一個(gè)<text>標(biāo)簽握玛。

{{userInfo.nickName}}包裹變量用兩個(gè)花括號(hào)包裝起來。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末次员,一起剝皮案震驚了整個(gè)濱河市败许,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌淑蔚,老刑警劉巖市殷,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異刹衫,居然都是意外死亡醋寝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門带迟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來音羞,“玉大人,你說我怎么就攤上這事仓犬⌒岽拢” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng)瘸味,這世上最難降的妖魔是什么蹂窖? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任围苫,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己谍夭,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布憨募。 她就那樣靜靜地躺著紧索,像睡著了一般。 火紅的嫁衣襯著肌膚如雪菜谣。 梳的紋絲不亂的頭發(fā)上齐板,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音葛菇,去河邊找鬼。 笑死橡羞,一個(gè)胖子當(dāng)著我的面吹牛眯停,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播卿泽,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼莺债,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了签夭?” 一聲冷哼從身側(cè)響起齐邦,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎第租,沒想到半個(gè)月后措拇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慎宾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年丐吓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趟据。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡券犁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出汹碱,到底是詐尸還是另有隱情粘衬,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站稚新,受9級(jí)特大地震影響勘伺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜枷莉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一娇昙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧笤妙,春花似錦冒掌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至召衔,卻和暖如春铃诬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背苍凛。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工趣席, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人醇蝴。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓宣肚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親悠栓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子霉涨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容