快應(yīng)用 tabs教程

2020-08-08 15:24 更新

了解如何使用tabs組件完成選項卡頁簽的布局,靈活組合組件,配置屬性,優(yōu)化性能

通過本節(jié),你將學(xué)會:

div組件模擬選項卡

選項卡效果常見于傳統(tǒng)H5開發(fā)中,開發(fā)者一般使用div和js代碼控制布局交互得以實現(xiàn)

在框架中,開發(fā)者也可以使用div組件實現(xiàn)簡單的效果,示例代碼如下:

<template>
  <div class="tutorial-page">
    <!-- div組件模擬選項卡功能 -->
    <div class="div-tabs">
      <!-- tabs的head部分 -->
      <div class="div-tabbar">
        <text onclick="showContent(1)">menu1</text>
        <text onclick="showContent(2)">menu2</text>
        <text onclick="showContent(3)">menu3</text>
      </div>
      <!-- tabs的body部分 -->
      <div class="div-tabcontent">
        <div class="div-tabcontent-section" show="{{type === 'content_1'}}">
          <text>content1</text>
        </div>
        <div class="div-tabcontent-section" show="{{type === 'content_2'}}">
          <text>content2</text>
        </div>
        <div class="div-tabcontent-section" show="{{type === 'content_3'}}">
          <text>content3</text>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    data: {
      type: 'content_1'
    },
    showContent (num) {
      this.type =  'content_' + num;
    }
  }
</script>

使用div組件實現(xiàn)的選項卡效果,功能還是有限,為了帶來最佳用戶體驗,建議使用框架提供的tabs組件完成需求

使用tabs組件

tabs中封裝了常見功能和效果:頁簽支持橫向滾動,支持手勢滑動切換內(nèi)容頁等

tabs內(nèi)部僅支持子組件tab-bartab-content,也可以只包含一個子組件,使用說明如下:

  • tab-bar組件用來包含所有頁簽的標(biāo)題,屬性mode用來配置是否可滾動,詳情請參考文檔:組件 -> 容器組件 -> tab-bar
  • tab-content組件用來包含所有頁簽的內(nèi)容,詳情請參考文檔:組件 -> 容器組件 -> tab-content
  • tab-bar組件的第n個直接子節(jié)點對應(yīng)tab-content中第n個直接子節(jié)點,具有聯(lián)動效果

示例代碼如下:

<template>
  <div class="tutorial-page">
    <!-- tabs組件 -->
    <tabs>
      <tab-bar class="tab-bar">
        <text>menu1</text>
        <text>menu2</text>
        <text>menu3</text>
      </tab-bar>
      <tab-content class="tab-content">
        <div class="tab-content-section">
          <text>content1</text>
        </div>
        <div class="tab-content-section">
          <text>content2</text>
        </div>
        <div class="tab-content-section">
          <text>content3</text>
        </div>
      </tab-content>
    </tabs>
  </div>
</template>

注意:

  • tabs內(nèi)不能再嵌套tabs,如有此類需求,請參考教程第一部分div組件模擬選項卡

頁簽內(nèi)容使用自定義子組件

為了更好的組織頁面代碼,提升代碼可維護(hù)性。開發(fā)者可以將頁簽內(nèi)容通過自定義子組件來渲染

關(guān)于如何開發(fā)子組件請參考文檔:父子組件通信 ,本小節(jié)僅做簡單引入使用

示例代碼如下:

<import name="tab-content-item" src="./tabitem"></import>

<template>
  <div class="tutorial-page">
    <tabs onchange="onChangeTabIndex">
      <tab-bar class="tab-bar">
        <text>menu1</text>
        <text>menu2</text>
        <text>menu3</text>
      </tab-bar>
      <tab-content class="tab-content">
        <tab-content-item index="0" itemdata="{{list[0]}}" current-index="{{currentIndex}}"></tab-content-item>
        <tab-content-item index="1" itemdata="{{list[1]}}" current-index="{{currentIndex}}"></tab-content-item>
        <tab-content-item index="2" itemdata="{{list[2]}}" current-index="{{currentIndex}}"></tab-content-item>
      </tab-content>
    </tabs>
  </div>
</template>

<script>
  export default {
    data: {
      list: [
        {title: "content1"},
        {title: "content2"},
        {title: "content3"}
      ],
      currentIndex: 0
    },
    onChangeTabIndex (evt) {
      this.currentIndex = evt.index
    }
  }
</script>

tabitem.ux文件中:

<template>

  <div class="tab-section">

    <text>{{itemdata.title}}</text>

  </div>

</template>

<style>

  .tab-section {

    flex: 1;

    flex-direction: column;

    justify-content: center;

    background-color: #ffffff;

    margin: 10px;

  }

  .tab-section text {

    color: #FF0000;

    text-align: center;

  }

</style>

<script>

  export default {

    props: [

      'index',

      'itemdata',

      // 駝峰式在賦值時使用-連接

      'currentIndex'

    ],

    onInit () {

      // 監(jiān)聽屬性變化

      this.$watch('currentIndex', 'watchCurrentIndex')

    },

    /**

     * 監(jiān)聽用戶選擇的索引,選中當(dāng)前時觸發(fā)業(yè)務(wù)邏輯

     * @param newValue

     * @param oldValue

     */

    watchCurrentIndex (newValue, oldValue) {

      if (parseInt(this.index) === this.currentIndex) {

        console.info(`當(dāng)前用戶選擇了這個標(biāo)簽:${this.index}, ${newValue}, ${oldValue}`)

      }

    }

  }

</script>

頁簽內(nèi)容懶加載

一個內(nèi)容豐富的選項卡,通常會包含許多頁簽內(nèi)容。如新聞類應(yīng)用中,可能會包括:推薦、熱點、視頻、段子、汽車、社會、娛樂等

直接使用tabs默認(rèn)會加載所有頁簽內(nèi)容,導(dǎo)致JS線程持續(xù)忙于渲染每個頁簽,無法響應(yīng)用戶點擊事件等,造成體驗困擾

為了解決這類問題,開發(fā)者可以讓頁簽內(nèi)容在用戶點擊時延遲渲染(而不是整個頁面初始化時渲染),這項功能可以通過if指令完成

示例代碼如下:

<template>
  <div class="tutorial-page">
    <tabs onchange="onChangeTabIndex">
      <tab-bar class="tab-bar" mode="scrollable">
        <text for="{{tabHeadList}}"  class="{{currentIndex === $idx ? 'active' : ''}}" >{{$item.title}}</text>
      </tab-bar>
      <tab-content class="tab-content">
        <div class="tab-content-section" for="{{tabHeadList}}">
          <!-- 初始化時,if為false,默認(rèn)不做渲染;點擊后改為true -->
          <text if="{{ renderTabContent($idx) }}">{{$item.title}}</text>
        </div>
      </tab-content>
    </tabs>
  </div>
</template>

<style lang="less">

  .tutorial-page {

    flex-direction: column;

    justify-content: center;

    align-items: center;

    .tab-bar text{

      padding: 0 25px;

      text-align: center;

      font-size: 34px;

    }

    .tab-bar .active {

      color: #FF0000;

    }

    .tab-content {

      flex: 1;

      background-color: #eeeeee;

      .tab-content-section {

        flex: 1;

        margin: 10px;

        background-color: #ffffff;

        justify-content: center;

        text {

          text-align: center;

          color: #FF0000;

        }

      }

    }

  }

</style>

<script> export default { data: { tabHeadList: [ {title: "推薦"}, {title: "熱門"}, {title: "視頻"}, {title: "段子"}, {title: "汽車"}, {title: "社會"}, {title: "娛樂"}, {title: "軍事"}, {title: "體育"}, {title: "NBA"}, {title: "財經(jīng)"} ], currentIndex: 0 }, onInit(){ // 加載第一個頁簽內(nèi)容 this.changeTabIndex(0) }, changeTabIndex(index) { const item = Object.assign({}, this.tabHeadList[index]) item.render = true this.tabHeadList.splice(index, 1, item) }, onChangeTabIndex (evt) { this.currentIndex = evt.index this.changeTabIndex(evt.index) }, renderTabContent (index) { return !!this.tabHeadList[index].render } } </script>

tabs僅包含tab-content

tabs內(nèi)部可以僅包含tab-bar或者tab-content

假設(shè)開發(fā)者有如下需求:開發(fā)一個簡化的社交主頁,其中,用戶圖標(biāo)和搜索圖標(biāo)為跳轉(zhuǎn)按鈕,點擊跳轉(zhuǎn)頁面;聊天、發(fā)現(xiàn)、通訊錄為頁簽,與內(nèi)容頁聯(lián)動,效果如下:


由于tabs僅支持子組件tab-bartab-content,且tab-bartab-content的直接子元素都被當(dāng)做頁簽或內(nèi)容頁。因此,僅使用tabs無法實現(xiàn)兩個圖標(biāo)按鈕

所以開發(fā)者可以這樣實現(xiàn):

  1. tabs中,僅使用tab-content,包含選項卡的所有內(nèi)容頁
  2. tabs外,使用div包含選項卡頁簽標(biāo)題及圖標(biāo)按鈕,模擬tab-bar
  3. 在js代碼中,動態(tài)綁定tabsindex屬性,監(jiān)聽tabschange事件,實現(xiàn)頁簽與內(nèi)容頁的聯(lián)動

示例代碼如下:

<template>
  <div class="tutorial-page">
    <!-- 靈活使用tabs組件 -->
    <div class="flexible-tabs">
      <!-- 自定義tab-bar組件 -->
      <div class="flexible-tabbar">
        <image src="./img/user.png" onclick="routePage('personal')"></image>
        <text class="{{currentIndex === 0 ? 'active' : ''}}" onclick="clickTabBar(0)">聊天</text>
        <text class="{{currentIndex === 1 ?  'active' : ''}}" onclick="clickTabBar(1)">發(fā)現(xiàn)</text>
        <text class="{{currentIndex === 2 ? 'active' : ''}}" onclick="clickTabBar(2)">通訊錄</text>
        <image src="./img/search.png" onclick="routePage('search')"></image>
      </div>
      <!-- 監(jiān)聽change事件,觸發(fā)時動態(tài)修改tabs的index屬性 -->
      <tabs onchange="changeTabactive" index="{{currentIndex}}">
        <tab-content class="flexible-tab-content">
          <div class="tab-content-section">
            <text>聊天</text>
          </div>
          <div class="tab-content-section">
            <text>發(fā)現(xiàn)</text>
          </div>
          <div class="tab-content-section">
            <text>通訊錄</text>
          </div>
        </tab-content>
      </tabs>
    </div>
  </div>
</template>

<style lang="less">

  .tutorial-page {

    flex: 1;

    .flexible-tabs {

      flex: 1;

      flex-direction: column;

      .flexible-tabbar {

        height: 100px;

        padding: 0 30px;

        background-color: #f1f1f1;

        align-items: center;

        text {

          flex-grow: 1;

          height: 100px;

          margin: 0 30px;

          text-align: center;

          border: 0px solid #f1f1f1;

          border-bottom-width: 5px;

        }

        image {

          height: 50px;

          width: 50px;

          resize-mode: contain;

        }

        .active {

          color: #0faeff;

          border-bottom-color: #0faeff;

        }

      }

      .flexible-tab-content {

        flex: 1;

        .tab-content-section {

          flex: 1;

          background-color: #ffffff;

          justify-content: center;

        }

      }

    }

  }

</style>

<script> import router from '@system.router' export default { data: { currentIndex: 0 }, changeTabactive (evt) { this.currentIndex = evt.index }, clickTabBar (index) { this.currentIndex = index }, routePage (param) { router.push({ uri: param }) } } </script>

總結(jié)

選項卡需求很常見,熟悉tabs組件的使用,有助于:提升用戶體驗、減少加載時間、優(yōu)化頁面性能


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號