【快應用】實現自定義導航欄組件

1. 簡介

導航欄組件,主要用於頭部導航。

導航欄(Nav_bar)組件結構大致分爲兩部分,一部分是圖標,另一部分是文本,子組件實現,父組件引用。

效果圖如下:

cke_710.png

基本佈局代碼如下:

<template>

  <div class="container">

    <text>本導航欄爲自定義組件,並非原生導航欄。除非原生導航欄無法滿足需求,否則不推薦使用自定義導航欄組件。</text>

    <text class="section">基本用法</text>

    <div class="example-body">

      <nav_bar height="50px" backgroundcolor="#ffffff" left-icon="{{leftIcon}}" title="標題" 

          @clickleft="back" title-style="font-size: 40px; color:red"></nav_bar>

</div>

</div>

<template>

2.開發指引

2.1自定義子組件

1.定義佈局樣式。

導航欄組件佈局包括三個部分:左側圖標內容部分、標題內容部分、右側圖標內容部分。

左側圖標內容部分、右側圖標內容部分通過image+text+slot組件實現

標題內容部分由text+slot組件實現。

代碼如下:

<template>

  <div>

    <div class="navbar_content" style="height:{{height}};background-color:{{backgroundcolor}}">

      <div class="navbar_btns_left" onclick="clickLeft">

        <div if="leftIcon.length">

          <image style="height: 50px" src="{{leftIcon}}"></image>

        </div>

        <div if="leftText.length">

          <text style="{{leftTextStyle}}">{{ leftText }}</text>

        </div>

        <slot name="left"></slot>

      </div>

      <div class="navbar_container" onclick="clickTitle">

        <text class="text_context" style="{{titleStyle}}" 

            if="title.length">{{ title }}</text>

        <slot name="mid"></slot>

      </div>

      <div class="navbar_btns_right" onclick="clickRight">

        <div if="rightIcon.length">

          <image style="height: 50px" src="{{rightIcon}}"></image>

        </div>

        <div class="*" if="rightText.length && !rightIcon.length">

          <text style="{{rightTextStyle}}">{{ rightText }}</text>

        </div>

        <slot name="right"></slot>

      </div>

    </div>

  </div>

</template>

2.2子組件設計

支持的屬性如下:

屬性名

類型

默認值

說明

title

String

null

標題文字

height 

String

null

導航欄高度

backgroundcolor

String

null

導航欄背景色

leftText

String

null

左側按鈕文本

rightText

String

null

右側按鈕文本

leftIcon

String

null

左側按鈕圖標

rightIcon

String

null

右側按鈕圖標

支持的事件:

事件名稱

說明

返回值

clickLeft

點擊當前點擊狀態

clickRight 

點擊當前點擊狀態

clickTitle

點擊當前點擊狀態

 

2.3父子組件通信

2.3.1父組件給子組件傳遞數據

子組件通過在props定義參數,接收來自父組件的傳值數據,如height、title等。如下圖所示:

  cke_16452.png 

cke_21738.png

cke_27159.png

2.3.2子組件通過this.$emit方法觸發父組件的自定義事件

cke_33780.png

3.總結

實現導航欄組件,您可以從中學會如下知識點:

l  熟悉快應用子組件的設計和屬性定義;

l  熟悉父子組件通信;

l  熟悉slot組件的運用;

  

想欲瞭解更多詳情,請參見:

華爲快應用官網:

https://developer.huawei.com/consumer/cn/doc/development/quickApp-References/quickapp-animation-styles-0000001123530340

 

最後附上完整的實現代碼:

導航欄組件nav_bar.ux

<template>

  <div>

    <div class="navbar_content" style="height:{{height}};background-color:{{backgroundcolor}}">

      <div class="navbar_btns_left" onclick="clickLeft">

        <div if="leftIcon.length">

          <image style="height: 50px" src="{{leftIcon}}"></image>

        </div>

        <div if="leftText.length">

          <text style="{{leftTextStyle}}">{{ leftText }}</text>

        </div>

        <slot name="left"></slot>

      </div>

      <div class="navbar_container" onclick="clickTitle">

        <text class="text_context" style="{{titleStyle}}" 

            if="title.length">{{ title }}</text>

        <slot name="mid"></slot>

      </div>

      <div class="navbar_btns_right" onclick="clickRight">

        <div if="rightIcon.length">

          <image style="height: 50px" src="{{rightIcon}}"></image>

        </div>

        <div class="*" if="rightText.length && !rightIcon.length">

          <text style="{{rightTextStyle}}">{{ rightText }}</text>

        </div>

        <slot name="right"></slot>

      </div>

    </div>

  </div>

</template>

<script>

  /** 

   * NavBar 自定義導航欄

   * @description 導航欄組件,主要用於頭部導航

   * @tutorial https://ext.dcloud.net.cn/plugin?id=52

   * @property {String} title 標題文字

   * @property {String} height 導航欄高度

   * @property {String} backgroundcolor 導航欄背景色

   * @property {String} leftText 左側按鈕文本

   * @property {String} rightText 右側按鈕文本

   * @property {String} leftIcon 左側按鈕圖標

   * @property {String} rightIcon 右側按鈕圖標

   * @property {String} leftTextStyle 左側按鈕文本樣式

   * @property {String} titleStyle 中間標題文本樣式

   * @property {String} rightTextStyle 右側按鈕文本樣式

   * @event {Function} clickLeft 左側按鈕點擊時觸發

   * @event {Function} clickRight 右側按鈕點擊時觸發

   * @event {Function} clickTitle 中間標題點擊時觸發

  */

  module.exports = {

    props: {

      height: {

        type: String,

        default: ""

      },

      backgroundcolor: {

        type: String,

        default: ""

      },

      title: {

        type: String,

        default: ""

      },

      leftText: {

        type: String,

        default: ""

      },

      rightText: {

        type: String,

        default: ""

      },

      leftIcon: {

        type: String,

        default: ""

      },

      rightIcon: {

        type: String,

        default: ""

      },

      leftTextStyle: {

        type: String,

        default: ''

      },

      titleStyle: {

        type: String,

        default: ''

      },

      rightTextStyle: {

        type: String,

        default: ''

      },

    },

 

    onInit() {

      this.$page.setTitleBar({ text: '自定義導航欄' })

    },

    clickLeft() {

      this.$emit("clickleft");

    },

    clickRight() {

      this.$emit("clickright");

    },

    clickTitle() {

      this.$emit("clicktitle");

    }

  }

</script>

 

<style>

  .navbar_content {

    display: flex;

    align-items: center;

    flex-direction: row;

  }

 

  .navbar_btns_left {

    width: 150px;

  }

  .navbar_container {

    width: 500px;

  }

  .text_context {

    width: 480px;

    text-align: center;

  }

  .navbar_btns_right {

    width: 150px;

    justify-content: flex-end;

  }

</style>

 

主頁面hello.ux

<import name="nav_bar" src="./Nav_bar/nav_bar.ux"></import>

<template>

  <div class="container">

    <text>本導航欄爲自定義組件,並非原生導航欄。除非原生導航欄無法滿足需求,否則不推薦使用自定義導航欄組件。</text>

    <text class="section">基本用法</text>

    <div class="example-body">

      <nav_bar height="50px" backgroundcolor="#ffffff" left-icon="{{leftIcon}}" title="標題" @clickleft="back" title-style="font-size: 40px; color:red"></nav_bar>

    </div>

    <text class="section">左右顯示文字</text>

    <div class="example-body">

      <nav_bar left-icon="{{leftIcon}}" left-text="返回" title="標題" left-text-style="font-size: 30px; color:red;" right-text="菜單" @clickleft="back" @clickTitle="showTitle"></nav_bar>

    </div>

    <text class="section">插入slot</text>

    <div class="example-body">

      <nav_bar right-icon="{{rightIcon}}" @clickleft="showCity" @clickright="scan">

        <div slot="left">

          <div>

            <text>北京</text>

            <image src="../Common/arrowdown.png"></image>

          </div>

        </div>

        <div slot="mid">

          <div class="input-view">

            <image style="height: 40px; margin-top: 15px" src="../Common/search.png"></image>

            <input enterkeytype="search" placeholder="輸入搜索關鍵詞" @enterkeyclick="confirm" />

          </div>

        </div>

      </nav_bar>

    </div>

  </div>

</template>

 

<script>

  import router from '@system.router'

  import prompt from '@system.prompt'

  export default {

 

    data() {

      return {

        city: "BeiJing",

        leftIcon: "../Common/leftIcon.png",

        rightIcon: "../Common/rightIcon.png"

      }

    },

 

    back() {

      router.back()

    },

    scan() {

      prompt.showToast({

        message: '掃碼',

        duration: "100000",

        gravity: 'center'

      })

    },

    showCity() {

      prompt.showToast({

        message: '選擇城市',

        duration: "100000",

        gravity: 'center'

      })

    },

    showTitle() {

      prompt.showToast({

        message: '標題',

        duration: "100000",

        gravity: 'center'

      })

    },

    confirm() {

      prompt.showToast({

        message: '搜索',

        duration: "100000",

        gravity: 'center'

      })

    }

  }

</script>

 

<style>

  .container {

    flex: 1;

    flex-direction: column;

    background-color: #ffffff;

  }

 

  .section {

    background-color: #afeeee;

    margin-top: 20px;

    margin-bottom: 20px;

    font-size: 30px;

    padding: 20px;

    width: 100%;

  }

  .example-body {

    flex-direction: row;

    padding: 10px;

    background-color: #ffffff;

    width: 100%;

  }

 

  .input-view {

    flex-direction: row;

    background-color: #f8f8f8;

    height: 60px;

    border-radius: 15px;

    margin-left: 60px;

    margin-right: 60px;

    line-height: 30px;

  }

</style>
欲瞭解更多更全技術文章,歡迎訪問https://developer.huawei.com/consumer/cn/forum/?ha_source=zzh
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章