最近公司項目不是很忙,有時間研究研究微信小程序。參考了目前市場上各種答題類的app、小程序等等,作了一款本身的微信答題小程序,包括前端和後端,後端是用node作的。如今已經上線了,名字叫【你問我猜猜猜】,你們感興趣的話能夠去試玩一下。css
若是以前用過vue或者react,直接看看文檔上手微信小程序徹底沒問題。總體開發思路很類似,包括其中的一些語法,基本上都是同樣的。或者用美團的mpvue框架,那就根本不用學習小程序的語法了,寫起來跟vue同樣。可是咱們開發的時候沒有用框架,用的是原生的微信小程序語言,開發起來也很easy。並且微信小程序有不少本身的API,好比圖片上傳、下載、音頻等等,項目中用到的時候再找文檔就來得及。前端
此次開發的難點,也是微信小程序的難點,應該就是在登陸了。若是把登陸流程弄明白了,在開發其餘的功能,基本上就是時間的問題了。vue
看了好多文檔關於登陸相關的介紹,下圖的介紹是比較詳細的過程,開發過程當中也是採用的這個邏輯。只不過咱們沒有獲取用戶的敏感信息,因此沒有七、8步驟。直接經過wx.getUserInfo()獲取到用戶名、頭像等信息便可知足咱們的需求。node
登陸的代碼以下:mysql
wx.getStorage({ key: "code", success: res => { wx.checkSession({ success: res => { console.log("Session未過時,登錄狀態未失效"); }, fail: err => { // 從新登陸 console.log("Session過時,從新登陸"); loginAction(); } }); }, fail: res => { console.log("無code信息,調用登陸接口獲取code"); loginAction(); } });
登陸的流程圖以下:
react
微信小程序沒有包管理這一說(可是最新版本的好像支持npm了),因此想要用到別的庫裏的組件,只能找到源碼,copy過來。git
有可能形成數據越權。好比今天我經過個人手機登陸了微信,打開了小程序。可是明天有個朋友想用個人手機登一下微信。若是用openid做爲登陸憑證,登陸小程序的時候檢測到openid已經存在,因此不會再走登陸過程,這樣個人數據就讓個人朋友看到了。因此仍是要按照官方推薦的步驟來。github
微信小程序默認都是https請求,若是本地開發聯調,須要在開發者工具 -> 項目設置裏,勾選上【不校驗合法域名、web-view(業務域名)、TLS 版本以及 HTTPS 證書】,這樣就能夠愉快的使用localhost訪問服務端了。web
一個經常使用的使用場景,用戶反饋裏,用戶巴拉巴拉吐槽完,點擊確認發送成功後,爲了防止用戶再次重複提交,須要將textarea中的數據清空。sql
用過vue的你們都知道,綁定一個字段,當成功後將這個字段賦值爲空就行了。but,微信小程序可不幹。
微信小程序文檔中這樣說明:不建議在多行文本上對用戶的輸入進行修改,因此 textarea 的 bindinput 處理函數並不會將返回值反映到 textarea 上。
如何解決呢。能夠給textarea綁定一個value值。用form表單去提交。成功後將value綁定的值清空就能夠了。
具體代碼以下:
<form bindsubmit="bindSubmit"> <textarea placeholder="若是您對咱們有任何建議或意見,請在此處向咱們提交,期待您的寶貴建議。" name="feedbackContent" value="{{feedbackContent}}" bindinput="bindTextAreaInput" /> <button class="submit-btn" form-type="submit" disabled="{{feedbackContent.length == 0 || btnLoading}}" loading="{{btnLoading}}" value="{{feedbackContent}}"> 提交 </button> </form> bindTextAreaInput: function(e) { this.setData({ feedbackContent: e.detail.value }); }, bindSubmit: function(e) { this.setData({ btnLoading: true }); addFeedbackRequest({ content: e.detail.value.feedbackContent.trim() }).then(res => { if (res.success) { this.setData({ btnLoading: false, feedbackContent: "" }); this.showToast("提交成功,感謝您的反饋"); } else { console.log("fail"); this.showToast("提交失敗,請稍後再試"); } }); },
給頁面添加背景是,若是經過background屬性來添加,抱歉,那你不能引用本地的圖片,只能引用通過base64轉碼的或者網上的圖片。
小程序的文檔上有說,本地資源是沒法經過css獲取的。可是經過image的src屬性引用的圖片,則沒有這個限制。
文檔上說明:爲了避免讓用戶在使用小程序時形成困擾,咱們規定頁面路徑只能是五層,請儘可能避免多層級的交互方式。
使用wx.navigateTo()的時候,規定層級不能超過5級。若是超過5級,頁面就出錯了。但wx.redirectTo()則無此限制。
注意:
wx.navigateTo()是保留當前頁面,跳轉到應用內的某個頁面,使用 wx.navigateBack 能夠返回到原頁面
wx.redirectTo()是關閉當前頁面,跳轉到應用內的某個頁面。
wx.request()是發送請求的api,若是每一個request請求都在header中從新一份session信息,必定很麻煩。因此基本上前端都會封裝一個新的請求函數,包括攜帶session信息,處理錯誤接口等功能。具體代碼以下:
const httpRequest = data => { return new Promise(function(resolve, reject) { console.log("http request", data.url); let code = ""; wx.getStorage({ key: "code", success: res => { code = res.data; console.log("http request success", code); //發起網絡請求 wx.request({ url: data.url, data: { ...data.data }, method: data.method, header: { code: code, "content-type": "application/x-www-form-urlencoded" }, success: function(res) { if (res.data.success) { resolve(res.data); } else { // console.log(JSON.stringify(res)); if (res.data.errorCode == 100) { goBackIndex(); } reject(res.data); } }, fail: function(res) { console.log(JSON.stringify(res)); if (res.data.errorCode == 100) { goBackIndex(); } reject(res); } }); }, fail: res => { console.log("http request failed", code); console.log("not found code in storage"); goBackIndex(); } }); }); };
有關本項目的具體代碼(包含先後端,後端用的think.js框架,數據庫用的mysql)已經放在github上,若有須要,歡迎clone,歡迎star。
小程序前端:https://github.com/510team/wx...
小程序後臺:https://github.com/510team/we...