值得記錄的(五)- 微信小程式自定義 tabbar

来源:https://www.cnblogs.com/evenyao/archive/2018/11/22/10001970.html
-Advertisement-
Play Games

一定的需求情況下,無法使用小程式原生的 tabbar 的時候,需要自行實現一個和 tabbar 功能一模一樣的自製組件。 查閱了海量的博客和文檔之後,親自踩坑。總結了三種在不使用微信小程式原生 tabbar的情況下自製 tabbar 的方法。並說說這幾種方法各自的特色。 類 navigator 跳轉 ...


一定的需求情況下,無法使用小程式原生的 tabbar 的時候,需要自行實現一個和 tabbar 功能一模一樣的自製組件。

查閱了海量的博客和文檔之後,親自踩坑。總結了三種在不使用微信小程式原生 tabbar的情況下自製 tabbar 的方法。並說說這幾種方法各自的特色。

類 navigator 跳轉方式

類 navigator 跳轉方式是我自己起的名稱,因為它的實現思路就是這個樣子的。期初參考 微信小程式自定義tabBar組件開發 這篇博文的思路。進行了這種方式的嘗試,併為後續提供瞭解決思路。在這次實踐的過程中使用了和該博文類似的目錄結構。

 

template 文件主要包含了 tabbar 的內容、邏輯、模板、樣式。

tabbar_template.js

//初始化數據
function tabbarinit() {
  return [
    {
      "current": 0,
      "pagePath": "/pages/travel_shop/travel/travel_index/travel_index",
      "iconPath": "/pages/img/[email protected]",
      "selectedIconPath": "/pages/img/[email protected]",
      "text": "首頁"
    },
    {
      "current": 0,
      "pagePath": "/pages/travel_shop/travel/travel_car/travel_car",
      "iconPath": "/pages/img/[email protected]",
      "selectedIconPath": "/pages/img/[email protected]",
      "text": "購物車"
    },
    {
      "current": 0,
      "pagePath": "/pages/travel_shop/travel/travel_my/travel_my",
      "iconPath": "/pages/img/[email protected]",
      "selectedIconPath": "/pages/img/[email protected]",
      "text": "我的"
    }
  ]

}
//tabbar 主入口
function tabbarmain(bindName = "tabdata", id, target) {
  var that = target;
  var bindData = {};
  var otabbar = tabbarinit();
  otabbar[id]['iconPath'] = otabbar[id]['selectedIconPath']   //換當前的icon
  otabbar[id]['current'] = 1;
  bindData[bindName] = otabbar
  that.setData({ bindData });
}

module.exports = {
  tabbar: tabbarmain
}

 

 

tabbar_template.wxml

<template name="tabBar">
  <view class="tabBar">
    <block wx:for="{{tabBar}}" wx:for-item="item" wx:key="tabBar">
        <view class="tabBar-item">
            <navigator open-type="reLaunch" url="{{item.pagePath}}">
                <view><image class="tabBar-icon" src='{{item.iconPath}}'></image></view>
                <view class="{{item.current== 1 ? 'tabBartext' :''}}">{{item.text}}</view>
            </navigator>
        </view>
    </block>
 </view>
</template>

 

tabbar_template.wxss

.tabBar-icon{
  width:54rpx;
  height: 54rpx;
}
.tabBar{
  width:100%;
  position: fixed;
  bottom:0;
  padding:10rpx;
  margin-left:-4rpx;
  background:#F7F7FA;
  font-size:24rpx;
  color:#8A8A8A;
  box-shadow: 3rpx 3rpx 3rpx 3rpx #aaa; 
  z-index: 9999;
}

 .tabBar-item{
  float:left;
  width: 33.333%;
  text-align: center;
  overflow: hidden;
}
/*當前字體顏色*/
.tabBartext{
  color: black;
}
.navigator-hover{
  background-color: rgba(0, 0, 0, 0);
}

 

而後在全局引入樣式

@import "/pages/travel_shop/travel/tabbar_template/tabbar_template.wxss";

 

併在每一個頁面的子文件(wxml、JS)中引入相應的內容

wxml 引入

<import src="/pages/travel_shop/travel/tabbar_template/tabbar_template.wxml"/>
<template is="tabBar" data="{{tabBar:bindData.tabBar}}"/>

 

JS 引入

var template = require("../tabbar_template/tabbar_template.js");

併在對應的 onLoad 生命周期中,註明它是哪一個 tabbar

  onLoad: function (options) {
    template.tabbar("tabBar", 1, this) //0表示第一個tabbar,這裡1表示第二個 tabbar 的 icon
  },

 

效果預覽

 

我們最終得到了效果,但這種效果帶了明顯的抖動閃爍。原因則是因為這種實現方式的本質是通過 navigator 和 JS 事件觸發實現頁面之間的跳轉。因此我開始找尋另一種實現的方式。在 微信小程式自定義tabBar組件開發 這篇博客的留言板,我發現該文的作者也發現了這種方式的不足,並提到可以通過可以把頁面都寫成組件 component 的方式實現更好的效果。

 

template 模板 / component 組件

在繼續查閱了一些關於小程式自定義 tabbar 的博客之後,找到了 微信小程式 - 自定義tabbar 這篇博文。按照這篇博文描述的結構,我也進行了嘗試。發現這種方式不會出現之前跳轉產生的那種閃爍現象出現。

 

之後再查閱 微信小程式 template 模板與 component 組件的區別和使用 這篇博文的時候瞭解到,如果當我們主要是為了展示頁面的時候,可以使用 template 方式。如果涉及到 tabbar 對應各個頁面的業務邏輯交互比較多,那就最好使用 component 組件。

因為這三個頁面涉及到了很多獨立的交互,所以我決定使用 component 組件的形式,將自定義的 tabbar 寫成一個頁面,然後將其他三個 tabbar 按鈕對應的頁面寫成三個 component 組件。這種方法和 Vue 中的組件化很相似,可以把單個組件文件夾當成 Vue 中的一個 .vue 文件。

component 與普通 page 類似,但是 JS 文件和 JSON 文件與頁面不同。

小程式組件 JS 模板

Component({
  /* 開啟全局樣式使用 */
  options: {
    addGlobalClass: true,
  },

  /* 組件的屬性列表 */
  properties: {
    name: {
      type: String,
      value: ''
    }
  },

  /* 組件的初始數據 */
  data: {

  },

  /* 生命周期函數 */
  lifetimes: {
    attached: function () { },
    moved: function () { },
    detached: function () { },
  },

  /* 組件的方法列表 */
  methods: {

  },
})

 

component 組件 JSON 文件

{
  "component": true,
  "usingComponents": {}
}

 

tabbar 引用和配置

引用組件 JSON

按照如圖的結構,三個 component 作為子組件,tabber 作為一個父級,因此它的 JSON 需要引入這三個 component 組件。

 
// travel.json
{
  "usingComponents": {
    "travel_car": "travel_car/travel_car",
    "travel_index": "travel_index/travel_index",
    "travel_my": "travel_my/travel_my"
  }
}

 

tabbar JS

而該頁面的 JS 僅僅只用來控制 tabbar 的 icon 選擇,和傳遞一個 index 告訴頁面該隱藏和顯示哪一個 component 組件。

// travel.js
let app = getApp()

Page({
  data: {
    currentTab: 0,
    items: [
      {
        "iconPath": "/pages/img/[email protected]",
        "selectedIconPath": "/pages/img/[email protected]",
        "text": "首頁"
      },
      {
        "iconPath": "/pages/img/[email protected]",
        "selectedIconPath": "/pages/img/[email protected]",
        "text": "購物車"
      },
      {
        "iconPath": "/pages/img/[email protected]",
        "selectedIconPath": "/pages/img/[email protected]",
        "text": "我的"
      }
    ]
  },
  //事件處理函數
  bindChange: function (e) {
    let that = this;
    that.setData({
      currentTab: e.detail.current
    });
  },
  swichNav: function (e) {
    let that = this;
    if (this.data.currentTab === e.target.dataset.current) {
      return false;
    } else {
      that.setData({
        currentTab: e.target.dataset.current
      })
    }
  },
  onLoad: function () {
    let that = this
    app.getUserInfo(function (userInfo) {
      that.setData({
        userInfo: userInfo
      })
    })
  }
})

 

tabbar WXML

直接使用之前 JSON 中引用過的標簽名,類似於 Vue 中使用模板標簽。這裡由於組件模板標簽不支持直接使用 hidden 屬性,所以在外包裹了一層 view 標簽用來添加 hidden屬性。

<view hidden="{{currentTab == 0? false: true}}">
  <travel_index/>
</view>
<view hidden="{{currentTab == 1? false: true}}">
  <travel_car/> 
</view>
<view hidden="{{currentTab == 2? false: true}}">
  <travel_my/>
</view>

<view class="nav-tabs">
  <view class="tab-list {{currentTab == idx ? 'active' : 'default' }}" wx:for="{{items}}" wx:key="prototype" wx:for-index="idx" wx:for-item="item" data-current="{{idx}}" bindtap="swichNav">
    <text class="tab-text" wx:for-index="idx" data-current="{{idx}}" src="{{currentTab == idx ? item.selectedIconPath : item.iconPath }}">{{item.text}}</text>
    <image class="iconPath" wx:for-index="idx" data-current="{{idx}}" src="{{currentTab == idx ? item.selectedIconPath : item.iconPath }}"></image>
  </view>
</view>

 

tabbar WXSS

Some selectors are not allowed in component wxss, including tag name selectors, ID selectors, and attribute selectors.(./pages/xxx/xxx.wxss:288:3)This wxss file is ignored.

造成這種報錯的原因是 component 組件的樣式中不能包含一些特定的選擇器。

page {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.nav-tabs {
  width: 100%;
  display: flex;
  position: fixed;
  bottom: 0;
}

.tab-list {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column-reverse;
  background: #fcfcfc;
}

.tab-text {
  font-size: 24rpx;
  line-height: 35rpx;
  color: #5f5f5f;
}

.iconPath {
  width:54rpx;
  height: 54rpx;
}

.tab-content {
  flex: 1;
}

.default {
  line-height: 75rpx;
  text-align: center;
  flex: 1;
  color: #eee;
  font-weight: bold;
  font-size: 28rpx;
}

.active {
  line-height: 75rpx;
  text-align: center;
  color: black;
  flex: 1;
  font-weight: bold;
  font-size: 28rpx;
}

.show {
  display: block;
  flex: 1;
}

.hidden {
  display: none;
  flex: 1;
}

 

預覽效果

最終就完成了一個非原生小程式 tabbar 的自定義 tabbar 。

 

 

參考

微信小程式自定義tabBar組件開發
微信小程式 - 自定義tabbar
微信小程式 template 模板與 component 組件的區別和使用


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 安裝 cordova 新建項目 運行項目 編譯項目 修改編譯輸出 打開vue項目目錄下麵的index.html,添加 打開/config/index.js 編譯打包 先刪除 cordova項目下的www文件夾里的東西 執行編譯vue項目將輸出到 cordova 項目目錄下的www文件內 添加andr ...
  • 寫JS時,不斷翻看HTML,確保`querySelector`能取到期望的元素。 改HTML時,一個個排查JS文件,確保其沒受影響。 類似的情況很影響我們工作效率。 ...
  • 基於CANVAS的簡單畫圖組件讓你用類似於dom的方式,在canvas上畫圖,感覺會不會很爽。 主頁:http://graph.jm47.com/示例:http://graph.jm47.com/example/index.html 安裝 直接從github下載 https://github.com ...
  • 有時候富文本渲染到頁面的時候 會連帶標簽一起渲染出來。 解決辦法: 首先引用 <script src="https://cdn.jsdelivr.net/npm/[email protected]/fuwenben.js"></script> 然後把富文本數據用 htmlDecode() 轉換一下 就可以 ...
  • input:focus{ outline: none; border: 1px solid #fff; } 或者 input[type=text]:focus{ outline: none; border: 1px solid #fff; } ...
  • @[toc] 構造函數與原型介紹 1.函數與函數的原型對象(prototype object): 在JavaScript中,創建一個函數A, 瀏覽器就會在記憶體中創建一個對象B,而且該函數預設會有一屬性 prototype 指向這個對象(即:prototype屬性的值) 這個對象B就是函數A的 原型對 ...
  • 變數 變數來源於數學,是電腦語言中能儲存計算結果或能表示值抽象概念。變數可以通過變數名訪問。 變數的作用就是用於存儲值。 語法: 聲明變數時,總是以關鍵字 打頭。任何情況下都應該這樣做。然後給變數指定名稱。在聲明變數時,也可以給它賦值,方法是在變數名後面加上等號和值。賦值語句總是以分號結束。 說明 ...
  • rem
    /** * @example 1rem=100px */!(function (doc, win) { var docEle = doc.documentElement, resizeEvent = 'orientationchange' in window ? 'orientationchange ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...