在前面隨筆的介紹中,我們已經為各種框架,已經準備了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 根據狀態碼自己去加入,如下程式碼所示。
使用者完成登入,併成功獲取身份資訊後,切換到指定的頁面,如下介面效果所示