初嘗微信小程序開發與實踐


這可能是一個java程序員最不務正業的一次分享了。

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

學習小程序,我認為對於后端同學還是比較有優勢的,因為后端同學對於HTML,CSS以及JS這些前端基本知識還是有所涉獵的,而前端的同學對於后端可能就沒那么了解了。接下來,以我的實踐經歷來簡單聊一聊小程序,算是總結也算是個分享。

小程序用來做什么?

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

入門小程序

首先開發小程序,需要一個專門的工具【微信開發者工具】,這個大家可以直接到微信公眾平台下載。

接下來我們首先新建個快速啟動模板看一下,如果你有注冊賬號有appid的可以填入,沒有的話也沒關系。點擊圖中小程序即可使用測試賬號。

如上圖,進入后即可看到這些文件。

可以說一個簡單的小程序只有這些了。

  • 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文件的構成,注釋很清晰:

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中上傳,具體地址在:https://github.com/allanzhuo/yyblog/tree/master/yymini

如果本文對您有幫助,或者項目能對您有所啟發的話,希望幫忙給yyblog項目點個Star吧,https://github.com/allanzhuo/yyblog

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM