自定義動態Tabbar導航欄
在默認的小程序開發中,定義tabbar,需要在App.json中配置如下json:
"tabBar": {
... "list": [
{ "text": "首頁",
"iconPath": "/public/images/index.png",
"selectedIconPath": "/public/images/index-act.png",
"pagePath": "pages/job/index"
} ... ]}
一經配置,無法修改。你可以調用setTabBarItem 設置按鈕文字、圖片路徑;就是無法動態設置跳轉地址、tabbar個數。
解決方案
我們需要新建一個中間頁面,用來控制所有tabbar,把tabbar要關聯的頁面,都用組件的方式來寫,這樣,我們只要在這一個頁面里,寫個fix在底部的tabbar樣式,點擊不同tab,顯示不同組件。
json文件
{
"usingComponents": {
"home" : "/pages/job/index", // 首頁
"company" : "/pages/company/company", // 公司
"message" : "/pages/chat/index", // 消息
"mine" : "/pages/mine/index", // 我的
"tabbar" : "/milfun/widget/custom-tab-bar", //自定義tabbar組件
}}
wxml文件
<!-- wxml中,把頁面設置成組件 -->
<home wx:if="{{activeTab == 'home'}}">首頁</home>
<company wx:if="{{activeTab == 'company'}}">公司</company>
<message wx:if="{{activeTab == 'message'}}">消息</message>
<mine wx:if="{{activeTab == 'mine'}}">我的</mine>
<!-- wxml中,自定義tabbar組件 -->
<tabbar list="{{tabList}}" bindmytab="tabChange"></tabbar>
js文件
Page({
data: { activeTab:'home' // company 、message、mine
}, onLoad: function (options) {
let tmp = 1; // 用來控制顯示不同方案的tabbar
if( tmp === 1 ){ // 顯示第一套tabbar
this.setData({ tabList:[ { "name": "...",
"text": "...",
"iconPath": "...",
"selectedIconPath": "...",
"pagePath": "..."
}, ... ] }) }else{ // 顯示第二套tabbar
this.setData({ tabList:[{},...] }) } }})
上面展示的是中間頁面的寫法,那正常頁面如何改成組件頁面呢?
頁面改成組件寫法
其不同主要是在于js文件里面的寫法不同,所以我們只看js部分:
正常寫法
Page({
data: {
}, onLoad: function (options) {
}, onShow: function (options) {
}, func1:function(e){
console.log(e)
}, func2:function(e){
console.log(e)
},})
組件寫法
Component({
options: { // 為了使用全局css樣式 addGlobalClass: true,
}, data: {}, /* * 組件被創建時調用,等同于上方的 onLoad */ attached: function (options) {
}, /* * 組件內部方法,等同于上方的自定義方法 */ methods: { func1:function(e){
console.log(e)
}, func2:function(e){
console.log(e)
}, }})
這樣,我們就實現了動態tabbar功能,tablist數據我們隨時都可修改,怎么跳轉,我們自己說了算!
輸入框彈起頁面上滑
遇見上面這個問題,我們的解決方案是:手動設置輸入框位置。
js文件
// 輸入框獲取焦點
foucus:function (e) {
this.setData({typerHeight: e.detail.height})},// 輸入框失去焦點blur:function () {
this.setData({typerHeight: 0})
},
wxml文件
<view class="tc-board" style="bottom:{{typerHeight}}px" >
......</view>
這樣,當輸入框獲取焦點時,會獲取到鍵盤的高度,然后把輸入框這個view的bottom樣式,設置成你獲取的高度,就完美的貼在輸入框上方。當輸入框失去焦點時,高度設置成0,輸入框view又回到了頁面的底部。
異步請求回調 + Token驗證
為了避免在業務中書寫繁雜的if else語句嵌套,或者回調函數
// 方法一
onLoad:function (e) {
// if嵌套
if(){
if(){
if(){ // do something }
} } // 回調陷阱 func1(data,func(){ func2(data,func(){ func3(data,func(){ // do something
}) }) })},
我的做法是,為方法添加promise,舉個例子:
公共功能js文件
/**
* 統一post請求接口 * @param {*} e “url,data,contentType,noOuth” */function post(e){
// token 保存在緩存中,有需要時調取 let header = { 'Content-Type': contentType, 'Authorization':'Bearer ' + getCache('accessToken') }
// 封裝在promise中 return new Promise(function (resolve, reject) {
wx.request({ url: config.domain + e.url , // domain統一放在config中
data:e.data, method: 'POST',
header: header, success: res => { // console.log(res)
if(res.data.code == 200 ){
resolve(res.data) // 請求成功,返回數據 } else{
wx.showToast({ title: res.msg, icon: 'none',
duration: 1500,
}); reject(res.data.msg) // 請求出錯,顯示錯誤 } }, fail: res => { // 請求失敗 wx.showToast({ title: '請求發送失敗',
icon: 'none',
duration: 1500,
}); } }) })}
頁面js文件
// 方法一
onLoad:function (e) {
fun.post({ url:'...',data:{...} })
.then( res => console.log(res) ) // 步驟一
.then( res => console.log(res) ) // 步驟二
.then( res => console.log(res) ) // 步驟三
.catch( res => console.log(res) ) // 捕捉異常
},
這樣寫起來思路清晰,優雅,感覺棒棒噠!
接口統一管理
有了上述的post接口,我們在開發中會有很多的請求接口,如果都寫在頁面中,難以管理,如有修改,要一個個頁面找過去,比較麻煩,我的做法是:
在模塊目錄下新建一個js,用來保存所有接口信息。為什么在模塊下呢?因為考慮到可能有不同的分包、如果都寫在一起會太多,分太細又帶來管理的不便,具體如何,請根據具體項目來操作。
api接口統一管理文件
/**
* 該模塊下所有接口
* 接口參數:
* url: just url
* contentType: default:false( use urlencoded ) or true( use json )
* noOuth: default:false( hase Authorization ) or true( no Authorization )
*/
const constApi = {
// 獲取用戶信息
getUserInfo : { // 定義接口調用的名字
url: 'api/v1/userinfo'
},
// 獲取用戶設置
getUserSetting: {
url: 'api/v1/usersetting',
outh:true // 需要鑒權
}
}
/**
* 對外接口統一調用
* @param {*} name 在api文件中的key
* @param {*} data 要post的數據
*/
const http = async function(key,data){
let api = constApi[key];
let response = await fun.post({
url:api.url,
data:data,
contentType:api.contentType,
outh:api.noOuth
})
return response
}
export default http
使用方法
// 導入api文件
import Api from './api-index.js'
onLoad:async function (e) { // 用法一
Api('getUserInfo ',{
userId:1,
userPwd:123456,
... }) .then( res => console.log(res) )
... // 用法二
let tmp = await Api('getUserInfo',{...})
this.setData({ list: tmp })
},
到時候如果接口修改了,或者地址更換了,就不用滿大街去找那些頁面用到了接口,一個個修改。只需要在api-index.js中,統一修改和管理了。
作者:MilFun
鏈接:https://juejin.im/post/6865920270218035214
來源:掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。