在前面隨筆的介紹中,我們已經為各種框架,已經准備了Web API、Winform端、Bootstrap-Vue的公司動態網站前端、Vue&Element的管理前端等內容,基本都是基於Web API基礎的。完成這些基礎准備和布局后,我們繼續將技術的觸角放到使用Vue語言開發小程序的場景中,本篇隨筆介紹使用uView UI+UniApp開發微信小程序,介紹使用准備過程中的一些注意點和經驗總結。
1、小程序的開發准備工作
我們在開發小程序之前,需要了解一些基本的知識,以及掌握一些常規的開發工具,相關知識最好能夠在着手開始前有所掌握,然后在開發過程中逐步加強鞏固即可。
1)Vue語言掌握
我們通過Vue官網https://cn.vuejs.org/v2/guide/index.html,了解相關的語言基礎只是,這個部分我們利用Vue開發小程序的基礎,必須先有所掌握相關基礎知識,以及開發組件中涉及到的知識點。
Vue可以是我們后續前端開發的強力助手,如果我們掌握的好,對很多相關的處理會一目了然,否則可能不明所以,如Mixin混入、以及組件的事件屬性的通訊關系、Vuex的存取處理、常用的JS模塊、ES6的函數定義及Promise的處理等等。
隨着我們對Vue開發的逐步熟悉,各種特性我們會一一記在腦中並能夠熟練運用。
2)UniApp官網
我們需要了解UniApp的基礎,包括它的相關理念,下面介紹的uViewUI本身也是基於它的進一步封裝,使用UniApp和HbuliderX 工具可以開發各種不同的小程序,APP、H5等場景,不過我們這里着重考慮微信小程序。
3)uView UI官網
通過官網https://www.uviewui.com/components/intro.html,了解組件的使用,以及一些基礎的知識,如easycom的約定、全局變量特別是Vuex的混入及使用過程、JS類庫等處理。
我們本次開發小程序,需要利用uView UI的組件代碼下載下來進行項目的整合使用,或者利用HBuilder X的工具,直接下載使用UniApp官網的uView UI插件模塊。
uView UI提供了各種界面上用到的組件,幾乎封裝了我們常見到的各種界面元素,極大的方便了我們小程序界面的開發工作,如果有些特殊的功能界面,也可以從UniApp官網的插件列表中尋找進行整合。
4)官方小程序網站
通過官網https://developers.weixin.qq.com/miniprogram/dev/framework/了解微信小程序的基礎知識,我們利用uView UI+UniApp開發微信小程序,本身還是對官方小程序接口的封裝處理,我們有時候還是需要對其中的相關生命周期,底層函數等有一定的了解,才能更好的理解微信小程序的各種機制和處理方式。
5)開發工具
我們這里開發UniApp程序,推薦還是使用HBuilderX來開發,相對通用的前端開發工具VS Code來說,它的有些處理更特性化,然后熟悉配合《微信開發者工具》進行小程序的調試和部署即可。
2、uView UI的使用
以Web API為業務數據的接口基石,我們可以擴展很多業務管理端,包括Winform端、Vue&Element業務管理端、動態門戶網站、微信小程序等等。
我們循例介紹一下uView UI的基礎使用步驟,首先在項目中main.js引入對應的組件-引入uView主JS庫。
// main.js import uView from "uview-ui"; Vue.use(uView);
檢查uni.scss中已經加入了uView UI的樣式,引入uView的全局SCSS主題文件
/* uni.scss */ @import 'uview-ui/theme.scss';
檢查app.vue中加入了對應的樣式,在App.vue
中首行的位置引入
<style lang="scss"> @import "uview-ui/index.scss"; @import "common/demo.scss"; </style>
一般來說,我們創建示例項目,都有這些基礎的設置了,我這里只是循例介紹一下,讓我們有所了解它的工作原理。
我這里還是主要介紹uView的this.$u的相關對象處理,它是通過Vue.prototype進行掛載進去的,也就是我們使用這些,都是uView加入的,如下main.js部分內容所示。
// 引入uView提供的對vuex的簡寫法文件 let vuexStore = require('@/store/$u.mixin.js') Vue.mixin(vuexStore) //引入后自動將Vuex里面的鍵作為Computed的屬性 // 引入uView對小程序分享的mixin封裝 let mpShare = require('uview-ui/libs/mixin/mpShare.js') Vue.mixin(mpShare)
在項目中,我們可以找到對應項目的store實現,以及uview對象Mixin混入的部分
它把登錄信息相關的用戶和令牌信息,通過storage的方式進行存儲起來,並處理好相關的邏輯,這樣混入后我們可以方便的通過混入的Computed屬性獲取到對應的值,或者快速的設置存儲起來。
這里的SaveStateKeys就是設置存儲到storage中的鍵,只要存在這兩個鍵的內容,都可以快速的使用Vuex的處理,如下是獲取內容。
<view class="u-flex-1"> <view class="u-font-16 u-p-b-20">用戶名稱:{{vuex_user.fullName}}</view> <view class="u-font-12 u-p-b-20">手機號:{{vuex_user.mobilePhone}}</view> <view class="u-font-12 ">郵箱:{{vuex_user.email}}</view> </view>
由於是頁面對象的自動混入,我們甚至在JS代碼里面都沒有定義這兩個對象,只需要記得這個鍵是我們的全局存儲的對象即可。
例如我們在JS的模塊里面,通過VM獲得this的參數
即可直接調用對象存儲處理,如下代碼所示。
//緩存其他信息
vm.$u.vuex('vuex_user.name', name) vm.$u.vuex('vuex_user.fullName', fullName) vm.$u.vuex('vuex_user.mobilePhone', mobilePhone) vm.$u.vuex('vuex_user.email', email) vm.$u.vuex('vuex_user.roles', roles) vm.$u.vuex('vuex_user.roles', roleNames)
如果是在頁面組件中,我們則使用this代替vm的變量進行調用
this.$u.vuex('vuex_user.name', name)
storage的信息,可以通過小程序的調試工具進行查看到,如下截圖所示。
3、小程序的登錄狀態判斷及跳轉
在業務系統中,我們需要根據登錄用戶的身份獲取對應的數據,如果用戶沒有登錄,這些信息是無法獲到的,那么我們可以在app.vue中判斷用戶是否登錄,然后調准到對應的頁面,如下所示。
跳轉判斷在app.vue的程序啟動邏輯中進行處理,如下代碼所示。
<script> export default { globalData: { username: '' }, onLaunch() { //如果用戶沒有登錄或令牌失效,跳轉到登錄界面 // console.log(this.vuex_token) if(!this.vuex_token) { this.$u.route({ url: 'pages/template/login/password' }); } else { uni.switchTab({ url: '/pages/example/myinfo' }); } }, } </script> <style lang="scss"> @import "uview-ui/index.scss"; @import "common/demo.scss"; </style>
其中 uni.switchTab 是跳轉到首頁的某個tab頁面,如果我們的頁面有tabbar頁面的話。
用戶登錄的時候,需要輸入用戶名,密碼,構建相關的參數后,進行登錄處理
submit() { this.$refs.uForm.validate(valid => { if (valid) { this.$u.api.User.login(this.model).then(data => { // 登陸成功跳轉到Tab頁面 uni.switchTab({ url: '/pages/example/myinfo' }); }); } else { console.log('驗證失敗'); } }); },
其中 this.$u.api.User 是用戶API接口的統一調用方式
我們在main.js代碼里面看到安裝了兩個不同的JS模塊,如下代碼所示。
// http攔截器,將此部分放在new Vue()和app.$mount()之間,才能App.vue中正常使用 import httpInterceptor from '@/common/http.interceptor.js' Vue.use(httpInterceptor, app) // http接口API抽離,免於寫url或者一些固定的參數 import httpApi from '@/common/http.api.js' Vue.use(httpApi, app)
其中第一個是統一http調用的設置,第二個這是引入一個api對象,方便調用api對應的接口,如下: this.$u.api.User
以及統一整合各個API對象
import User from '../api/user.js' // 此處第二個參數vm,就是我們在頁面使用的this,你可以通過vm獲取vuex等操作,更多內容詳見uView對攔截器的介紹部分: // https://uviewui.com/js/http.html#%E4%BD%95%E8%B0%93%E8%AF%B7%E6%B1%82%E6%8B%A6%E6%88%AA%EF%BC%9F const install = (Vue, vm) => { // 將各個定義的接口名稱,統一放進對象掛載到vm.$u.api(因為vm就是this,也即this.$u.api)下 vm.$u.api = { // 將 vm 對象傳遞到模塊中 User: User(vm) } } export default { install }
其中在http.interceptor.js里面,統一設置了api的Url的baseUrl,這樣可以不用配置反向代理的轉義,就可以簡化API中URL的定義了。
const install = (Vue, vm) => { Vue.prototype.$u.http.setConfig({ baseUrl: 'http://localhost:27206/', //接口訪問基礎路徑 showLoading: true, // 是否顯示請求中的loading loadingText: '請求中...', // 請求loading中的文字提示 loadingTime: 800, // 在此時間內,請求還沒回來的話,就顯示加載中動畫,單位ms // 如果將此值設置為true,攔截回調中將會返回服務端返回的所有數據response,而不是response.data // 設置為true后,就需要在this.$u.http.interceptor.response進行多一次的判斷,請打印查看具體值 // originalData: true, // 設置自定義頭部content-type // header: { // 'content-type': 'application/json;charset=UTF-8' // } })
另外我們返回的Response對象里面,有統一定義對象的,相關的數據可以參考隨筆《利用過濾器Filter和特性Attribute實現對Web API返回結果的封裝和統一異常處理》了解。
一旦程序處理過程中,有錯誤拋出,都會統一到這里進行處理,有異常的返回JSON如下所示。
其中結果result是用於檢查是否執行成功的標識,這里用來判斷是否有錯誤即可,有錯誤,則顯示自定義錯誤信息
// 響應攔截,判斷狀態碼是否通過 Vue.prototype.$u.http.interceptor.response = res => { // console.log(res) // 如果把originalData設置為了true,這里得到將會是服務器返回的所有的原始數據 // 判斷可能變成了res.statueCode,或者res.data.code之類的,請打印查看結果 if (!vm.$u.test.isEmpty(res.success)) { // res為服務端返回值,可能有code,result等字段 // 這里對res.result進行返回,將會在this.$u.post(url).then(res => {})的then回調中的res的到 // 如果配置了originalData為true,請留意這里的返回值 return res.result } else { var msg = '' var data =res.result if (data && data.error && data.error.message) { msg = data.error.message vm.$u.toast(msg) } // 如果返回false,則會調用Promise的reject回調, // 並將進入this.$u.post(url).then().catch(res=>{})的catch回調中,res為服務端的返回值 return false } }
上面的攔截默認是基於狀態碼200的,如果我們自定義一些異常,指定了狀態碼的也需要攔截,需改uview-ui/libs/request/index.js 根據狀態碼自己去加入,如下代碼所示。
用戶完成登錄,並成功獲取身份信息后,切換到指定的頁面,如下界面效果所示