初嘗微信小程序開發與實踐經驗分享

一個java程序員最遊手好閒的一次分享了。css

小程序的火熱相信不用我多說了,年初的時候老婆去浦東某達面試,甚至都被問有沒有小程序測試經驗。儼然小程序成爲了互聯網公司自PC,WAP,安卓,IOS以後又一不可或缺的入口。正好這段時間公司也在作一款小程序,因而順便也學習了一把。固然由於我是一個javaer,天然是之後端的視角來談談,和前端的同窗確定仍是比不上的。html

學習小程序,我認爲對於後端同窗仍是比較有優點的,由於後端同窗對於HTML,CSS以及JS這些前端基本知識仍是有所涉獵的,而前端的同窗對於後端可能就沒那麼瞭解了。接下來,以個人實踐經從來簡單聊一聊小程序,算是總結也算是個分享。前端

小程序用來作什麼?

「觸手可及」,「用完即走」。感受這兩個詞把小程序的特色描述的真的是淋漓盡致。以微信的用戶量,小程序免去了用戶還需安裝APP的繁瑣。並且用完以後,無需刻意退出,直接離開便可,當下次某個時間點在想起來,從新翻出來就好了。這對不少行業來講多是顛覆性的。以我我的的觀點來看,小程序適合作一些業務簡單,性能要求不高,使用頻率相對較低的應用。好比像垂直電商行業就是典型的受益者,自媒體電商,生鮮電商,若是讓用戶去下載一個這樣的APP成本是很大的,而使用小程序確悄然的避免了拉新客的難題。又好比我本身,若是我把本身的博客作成了一個APP,相信幾乎不會有同窗去下載,而使用小程序卻偶爾還會有些同窗會點進來看看的,哈哈。java

入門小程序

首先開發小程序,須要一個專門的工具【微信開發者工具】,這個你們能夠直接到微信公衆平臺下載。git

接下來咱們首先新建個快速啓動模板看一下,若是你有註冊帳號有appid的能夠填入,沒有的話也不要緊。點擊圖中小程序便可使用測試帳號。程序員

如上圖,進入後便可看到這些文件。github

能夠說一個簡單的小程序只有這些了。web

  • app.js 主要是全局公共的js方法聲明及調用所在的文件
  • app.json 是小程序全局的配置文件,因此有的頁面都在要此註冊,否則不容許訪問
  • app.wxss 是小程序全局的css文件
  • pages下是對應着全部頁面,每一個頁面,能夠添加四種類型的文件,.json,.wxss,.wxml,.js

另外在說下這四種類型的文件,小程序pages下面基本上每一個文件夾至關於一個頁面,每一個文件夾下面有四種命名相同但類型不一樣的文件,這四種構成了頁面的所有。面試

  • .json 後綴的 JSON 配置文件
  • .wxml 後綴的 WXML 模板文件,相似web開發的html
  • .wxss 後綴的 WXSS 樣式文件,相似web開發的css
  • .js 後綴的 JS 腳本邏輯文件,它就是一個js啊,不太小程序的js不能操做dom,是基於數據綁定的哦

而後咱們在看下js文件的構成,註釋很清晰:ajax

Page({

  /**
   * 頁面的初始數據
   */
  data: {
    
  },

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

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

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

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

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

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

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

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {
    
  }
})複製代碼

瞭解了這些基本上小程序開發就沒問題了,其餘就剩翻文檔了。這裏我建議把文檔當成字典來讀,讀完簡易教程和框架後,其餘須要什麼來查什麼就好了,不必像教科書同樣一字不落的全看完。

由於微信開發者工具還比較初始,以前每建一個頁面,我都是先建一個文件夾,而後在分別把四個文件建好。這裏我介紹個小技巧,你們能夠首先將要新建的頁面註冊進app.json,這時候工具會自動把文件夾和四種文件給你建好。說實話很奇怪,這種方法在官方文檔上我並無看到,不知道是我眼花仍是官方真的沒有寫。

{
  "pages":[
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle":"black"
  }
}複製代碼

再說下頁面的註冊,當咱們在app.json文件中註冊的時候,【pages/index/index】會將該頁面下index.xx的四種文件加載進來,而沒必要一個個寫了。還有就是文件夾名字和文件名是能夠不一樣的,好比【pages/index/launch】會將index文件夾下全部的launch文件加載。可是建議仍是同樣把,否則看着挺彆扭的。

最後在多說句,小程序的域名白名單問題,我發現不少同窗不知道,包括身邊的同事,一直還在用內網穿透來開發。

首先小程序對應用請求的域名是有限制的。

  1. 請求的域名必須在後臺配置,非配置域名沒法請求成功。
  2. 域名協議必須是https的,若是是http請求也是會失敗的

固然,這是對線上版原本說。若是是咱們本地開發,小程序提供了一個很人性化的功能。能夠忽略這個限制,甚至你能夠直接請求本地的IP地址+端口號,而沒必要使用繁瑣的內網穿透的方式了。

具體操做方式就是在微信開發者工具中,點擊【設置】-【項目設置】-【勾選】不校驗合法域名、web-view(業務域名)、TLS 版本以及 HTTPS 證書 便可,以下圖

下面就結合個人實踐小程序來簡單聊一聊,更多的資料你們能夠查閱文檔

開源實踐

恰巧前段時間作了個練手的yyblog的開源項目,此次就拿這個項目作個簡單的小程序客戶端了。仍是慣例,你們先看下效果圖吧。

單純的html,css,js實現,沒有應用任何前端框架,仍是比較適合參考學習的。ppps:反正我是不會說由於我不會纔不用的 嗚嗚~~~流下了沒有技術的淚水┭┮﹏┭┮。

微信小程序總的來講雖然已經上線那麼久,但和傳統意義上的開發語言上比,還不是那麼穩定的,官方也在不斷的調整中。

相信不少同窗有遇到過這樣的場景,當你第一次進入一個小程序的時候,會彈出來一個用戶信息受權的彈窗。剛開始我寫的時候也是這樣處理的,可是後來在上傳代碼的時候看到,微信在9月12號的時候發了一個公告。

主要是取消了分享監聽接口的回調,將獲取用戶信息的getUserInfo接口改成只有用戶點擊了相關受權組件才能觸發,還有就是openSetting接口也改成了點擊才能觸發。因此作微信小程序開發仍是要作關注下官方的動態,以避免作好的功能確不能正常使用的尷尬。

全局配置

前面有說app.xx的相關文件,是小程序的全局配置文件,這裏在單獨說下app.js這個文件。當咱們某些參數是全局須要的時候,咱們就能夠將相關的參數寫在這個文件裏面,好比咱們請求的基礎url,亦或是用戶信息,用戶ID這種請求必須攜帶的參數。同時咱們能夠將版本校驗的代碼寫在這裏,這裏在多說一句,微信是支持版本校驗的,當有新的版本代碼的時候,能夠作用戶更新提示,這裏再也不須要咱們後臺校驗,仍是比較方便的。相關的代碼以下:

App({

  onLaunch() {
    this.checkUpdate();
  },

  globalData: {
    userInfo: {},
    apiBase: "https://www.laoyeye.net",
    userId: ""
  },

  checkUpdate() {
    const updateManager = wx.getUpdateManager();
    updateManager.onCheckForUpdate(function (res) {
      // 請求完新版本信息的回調
      console.log(res.hasUpdate)
    })
    updateManager.onUpdateReady(function () {
      wx.showModal({
        title: '更新提示',
        content: '新版本已經準備好,是否重啓應用?',
        success: function (res) {
          if (res.confirm) {
            // 新的版本已經下載好,調用 applyUpdate 應用新版本並重啓
            updateManager.applyUpdate()
          }
        }
      })
    })

    updateManager.onUpdateFailed(function () {
      // 新版本下載失敗
      console.log('更新失敗!')
    })
  }
})複製代碼

啓動頁

用戶在剛開始進入小程序的時候,首先會展示一個啓動頁。起初我也不是這樣設計的,基本上是用戶進入後直接進入主頁,彈出用戶受權就好了,可是由於9.12的調整,也不得不做出了修改。讓用戶首先進入啓動頁受權,受權後跳轉到主頁。已受權的用戶就把受權按鈕隱藏,而後在等待1.5s後跳轉到主頁。這個過程當中我除了作了獲取用戶受權的操做以外,還請求後臺服務器在後臺建立了用戶數據,最終將userId返回到小程序。之後用戶作評論,點贊,收藏等操做,均會攜帶userId,方便區分具體的用戶。

這個頁面其實有兩個比較重要的知識要點,這裏特別強調下。

首先,咱們須要獲取每一個用戶對於當前應用的openId,以便下次用戶訪問時,避免再次受權的重複操做。

調用wx.login()接口獲取登陸憑證(code)進而換取用戶登陸態信息,包括用戶的惟一標識(openid) 及本次登陸的 會話密鑰(session_key)等。可是須要注意的是,用code去換取openid的操做,須要在服務端後臺來作,若是在小程序js上交換,在開發版本你會看到也是能夠正常獲取登陸,可是到生產上就不行了,由於小程序的安全限制,官方的域名是沒法設置到白名單裏。

代碼以下:

login(auth) {
    let that = this;
    //調用微信登陸接口
    wx.login({
      success: function(res) {
        wx.request({
          url: app.globalData.apiBase + '/api/wx/login?code=' + res.code + '&nickname=' + app.globalData.userInfo.nickName +
            '&avatar=' + app.globalData.userInfo.avatarUrl,
          header: {
            'content-type': 'application/json'
          },
          success: function(res) {
            //userId
            if (res.data.code == 200) {
              app.globalData.userId = res.data.data;
              console.log('獲取用戶信息=' + res.data.data);
              if (auth == 'auth') {
                that.direct();
              } else {
                let timer = setTimeout(() => {
                  clearTimeout(timer)
                  that.direct()
                }, 1500)
              }
            }
          }
        })
      }
    })
  },複製代碼

第二,就是getUserInfo這個接口了,由於新規定的限制,以往若是用戶沒有受權,是會彈出受權的彈窗的。可是新規定以後若是你調用這個接口是在用戶沒有受權的狀況下,那麼會直接進入fail失敗的回調的。因此你必須經過組件獲取用戶的受權,而後在用戶點擊的回調裏在調用這個方法。

代碼以下:

<button class="show-btn" wx:if="{{userInfo.length == 0}}" type="primary" open-type="getUserInfo" bindgetuserinfo="onGetUserInfo"> 受權登陸 </button>複製代碼
onGetUserInfo() {
    var that = this;
    wx.getSetting({
      success: function(res) {
        if (res.authSetting['scope.userInfo']) {
          wx.getUserInfo({
            success: function(res) {
              app.globalData.userInfo = res.userInfo;
              that.login('auth');
            },
            fail: function() {
              console.log('系統錯誤')
            }
          })
        } else {
          wx.showToast({
            title: "受權失敗",
            duration: 1000,
            icon: "none"
          })
        }
      },
      fail: function() {
        console.log('獲取用戶信息失敗');
      }
    })
  },複製代碼

最後,這裏在講個小問題,我不知道是否是我我的的問題,我在作頁面數據賦值的時候,會使用

this.data.requestUrl = requestUrl;
或者
this.setData({
postList: totalData
});

的方法。若是是異步狀況下,必須使用方法二,頁面上才能取到數據。可是有些狀況下非異步方法裏使用方法一數據居然取不出來,但是我在斷點中明明看到數據是賦值成功的啊。而這個時候換成方法二卻又成功了。真的是不明因此,你們儘可能使用方法二吧。

主頁、技術頁

把這兩個頁面一塊兒講,緣由就是兩個頁面雖然展示形式上不一樣,可是技術特色上仍是想同的。惟一的區別,可能就是後期我會把兩個頁面的數據接口作個調整,請求不一樣的數據了。

這個頁面主要是兩個知識點,上拉加載更多和下拉刷新了。

首先是上滑加載更多數據,這個實際上是小程序官方提供的一個onReachBottom的方法,只要用戶上滑到必定距離就會觸發,這裏我作了分頁的處理。首次進入展現五條數據,當觸發事件後請求第二頁的數據。固然請求到第二頁的數據並不能覆蓋以前的數據哦,否則當用戶在下滑時,剛纔的數據沒了,是不符合用戶習慣的。

上滑事件觸發的距離也是能夠經過onReachBottomDistance實現的,默認50px

具體實現的代碼以下:

// 上滑加載更多數據
  onReachBottom: function (event) {
    var nextUrl = this.data.requestUrl +
      "?page=" + this.data.page + "&limit=5";
    util.ajax(nextUrl, "get", null, this.processData)
    wx.showNavigationBarLoading()
  },複製代碼
processData: function (indexData) {
    var totalData = {};
    //若是要綁定新加載的數據,那麼須要同舊有的數據合併在一塊兒
    if (!this.data.isEmpty) {
      totalData = this.data.postList.concat(indexData);
    }
    else {
      totalData = indexData;
      this.data.isEmpty = false;
    }
    this.setData({
      postList: totalData
    });

    this.data.page += 1;
    wx.hideNavigationBarLoading();
    wx.stopPullDownRefresh();
  },複製代碼

而後是下拉刷新,下拉刷新默認是不開啓的,須要咱們在*.json配置中經過enablePullDownRefresh屬性開啓,默認爲false。

若是在app.json中設置爲全局開啓下拉刷新,在具體頁面中即爲當前頁面開啓。

相關代碼以下:

{
  "navigationBarTitleText":"小賣鋪的老爺爺",
  "enablePullDownRefresh": true
}複製代碼
onPullDownRefresh: function (event) {
    var refreshUrl = this.data.requestUrl +
      "?page=0&limit=5";
    this.data.techList = {};
    this.data.isEmpty = true;
    this.data.page = 1;
    util.ajax(refreshUrl, "get", null, this.processData);
    wx.showNavigationBarLoading();
  },複製代碼

其實這兩種方法,在你們看官方文檔全局配置的時候就會看到的。上面我也有說過學習小程序,官方文檔的簡易教程和框架仍是必看的,其餘的就沒那麼重要了。

詳情頁

詳情頁其實就一個要講,富文本的解析。

由於微信小程序並不支持html語言,因此須要轉換爲微信支持的wxml。

總的來講微信對富文本的支持並很差,官方也沒什麼好用的富文本解析組件。此次我使用的是github上關注度最高的小程序富文本組件wxParse ,雖然說相對比較完善了,BUG仍是很多的,並且做者好像也不維護了。可是目前實在沒有找到其餘什麼好的替代方案,只能用這個了。若是你們還有其餘組件,能夠告訴我一下哈。

wxParse 的使用,項目上已經講的很清楚了,你們方即可以移步:https://github.com/icindy/wxParse 查看。

我這邊對wxParse作了一些小改動,主要解決部分手機報錯沒法解析的問題。緣由是微信小程序不支持console.dir()的寫法,這個小程序官方也有在社區說明。

分享

當你在頁面的js文件中,定義了onShareAppMessage函數,這時候頁面便擁有了分享功能,能夠轉發給微信好友。

/**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {
    return {
      title: this.data.postData.title,
      path: '/pages/post-detail/post-detail?id=' + this.data.id + "&title=" + '小賣鋪的老爺爺' + "&share=1" 
    }
  },複製代碼

如上,是個人分享代碼,設置了分享的標題,以及跳轉的路徑等。這裏我對路徑作了參數處理,以便我能區分出用戶的來源。爲何要區分用戶來源呢,由於小程序的分享頁面進入後有個很奇怪的問題,沒有返回主頁的按鈕。因此我這邊單獨作了區分,當用戶來自分享時,顯示一個懸浮的返回首頁的圖標。

相關代碼以下:

<!-- 回到首頁(分享的時候顯示) -->
<image wx:if="{{share}}" bindtap='onBackHome' class='back-home' src='/images/icon/home-page.png' lazy-load></image>複製代碼
/**
  * 回到首頁(分享的時候)
  */
  onBackHome: function () {
    wx.reLaunch({
      url: '/pages/launch/launch?share=1"'
    })
  }複製代碼

個人

最後在說說個人這個頁面,其實這個頁面沒啥重要的東西。只是靜態頁面的跳轉。

我的信息後期我會作成可綁定PC端帳戶的形式。

個人收藏是已經實現過的,只是可能詳情頁尚未具體收藏的入口,後期我會加上。具體的效果圖以下。

還有一個就是打賞讚助這個頁面,剛開始是準備作成小程序間關聯,使用給贊api的接入方式。可是最近小程序官方對多個小程序間的跳轉也要增長限制,就懶得弄了。

直接作了個詳情頁的跳轉,詳情頁面貼了張讚揚碼完事。須要注意的是小程序頁面並不支持直接長按掃描哦,須要點擊下圖片,在彈出的圖片上在長按識別圖中的二維碼。

ppps:寫完文章後纔想起來這個頁面忘記說一個東西。小程序是可使用阿里icon庫的,具體使用方法你們網上看看吧。不說了,有興趣的也能夠看下我源碼中的實現。

最後的最後

附上小程序微信預覽地址:

以前有說這個項目是基於我前面的開源項目yyblog來寫的,因此項目的PC端是已經完成的。全部請求的接口均已在yyblog實現。

小程序的源碼也已在yyblog中上傳,具體地址在:github.com/allanzhuo/y…

若是本文對您有幫助,或者項目能對您有所啓發的話,但願幫忙給yyblog項目點個Star吧,github.com/allanzhuo/y…

篇幅有限,寫得有點長了,就到這裏吧。總的來講技術難度不大,可是小坑仍是比較多的。若是您有什麼想法歡迎在評論中與我交流,碼字不易,記得幫忙點個Star哦~

相關文章
相關標籤/搜索