1. 簡介
導航欄組件,主要用於頭部導航。
導航欄(Nav_bar)組件結構大致分爲兩部分,一部分是圖標,另一部分是文本,子組件實現,父組件引用。
效果圖如下:
基本佈局代碼如下:
<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等。如下圖所示:
2.3.2子組件通過this.$emit方法觸發父組件的自定義事件
3.總結
實現導航欄組件,您可以從中學會如下知識點:
l 熟悉快應用子組件的設計和屬性定義;
l 熟悉父子組件通信;
l 熟悉slot組件的運用;
想欲瞭解更多詳情,請參見:
華爲快應用官網:
最後附上完整的實現代碼:
導航欄組件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