前言
上一篇簡單的介紹了一下什么是組件,即組件是一個單獨且可復用的功能模塊的封裝。所以這篇文章主要在實際開發中自己動手封裝一個簡單的導航欄組件,當然在插件市場有很多,但是自己動手封裝一個才能真正領會其中的意義。
一、自定義組件
1.創建components文件夾
在項目根目錄下創建components文件夾用于保存自己自定義的組件
2.新建titlebar組件
<template><view class="nav-bar" :style="{ paddingTop: statusBarHeight + 'px' }"><!-- 左側返回按鈕(靠左) --><view class="nav-btn left-btn" @click="handleBack"><image class="back-image" src="/static/icon_left_back.png" mode="aspectFit" v-if="showBack"></image></view><!-- 動態標題(居中) --><view class="nav-title">{{ title }}</view><!-- 右側刷新按鈕(靠右) --><view class="nav-btn right-btn" @click="handleRefresh" v-if="showRefresh"><text>更新</text></view></view>
</template>
<script>export default {props: {title: {type: String,default: '默認標題'},showBack: {type: Boolean,default: true},showRefresh: { type: Boolean,default: false},},data() {return {statusBarHeight: 0}},mounted() {this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight || 0;},methods: {// 添加 handleBack 方法handleBack() {this.$emit('back'); // 觸發父組件的 @back 事件},// 添加 handleRefresh 方法handleRefresh() {this.$emit('refresh'); // 觸發父組件的 @refresh 事件}}}
</script><style scoped>.nav-bar {width: 100%;height: 88rpx;display: flex;align-items: center;justify-content: space-between;/* 關鍵:左右按鈕靠邊 */position: relative;box-sizing: content-box;background-color: #fff;}/* 左右按鈕樣式 */.nav-btn {height: 100%;display: flex;align-items: center;padding: 0 24rpx;z-index: 10;flex-shrink: 0;/* 防止按鈕被壓縮 */}/* 左側按鈕靠左 */.left-btn {justify-content: flex-start;min-width: 80rpx;/* 確保點擊區域足夠 */}/* 右側按鈕靠右 */.right-btn {justify-content: flex-end;min-width: 80rpx;color: #4292E4;}/* 標題居中(通過 flex: 1 填充中間空間) */.nav-title {flex: 1;text-align: center;font-size: 32rpx;color: #333;font-weight: 500;/* 防止標題文字被按鈕遮擋 */padding: 0 100rpx;/* 根據按鈕寬度調整 */box-sizing: border-box;}/* 返回圖標樣式 */.back-image {width: 40rpx;height: 40rpx;}
</style>
外層容器 (
nav-bar
)- 設置了動態的
padding-top
,值為statusBarHeight
,用于適配不同設備的狀態欄高度 - 使用
flex
布局,子元素水平排列
- 設置了動態的
左側返回按鈕 (
left-btn
)- 顯示返回圖標(通過
v-if="showBack"
控制是否顯示) - 點擊觸發
handleBack
方法 - 圖標使用
aspectFit
模式保持比例
- 顯示返回圖標(通過
中間標題 (
nav-title
)- 顯示動態標題文本(通過
title
prop 傳入) - 使用
flex: 1
占據剩余空間實現居中效果
- 顯示動態標題文本(通過
右側刷新按鈕 (
right-btn
)- 顯示"更新"文字(通過
v-if="showRefresh"
控制是否顯示) - 點擊觸發
handleRefresh
方法
- 顯示"更新"文字(通過
Props 定義
title
: 導航欄標題,默認為"默認標題"showBack
: 是否顯示返回按鈕,默認為true
showRefresh
: 是否顯示刷新按鈕,默認為false
數據
statusBarHeight
: 存儲設備狀態欄高度,初始為0
生命周期及方法
mounted
鉤子中獲取系統信息,設置狀態欄高度handleBack
: 點擊返回按鈕時觸發,向父組件發射back
事件handleRefresh
: 點擊刷新按鈕時觸發,向父組件發射refresh
事件
二、組件注冊
? 局部注冊(頁面級別組件)
<template><view class="content"><titlebar :title="pageTitle" :showBack="true" :showRefresh="true" @back="onBack" @refresh="onRefresh"></titlebar></view>
</template><script>import titlebar from '@/components/titlebar.vue';export default {components: {titlebar},data() {return {pageTitle: '自定義標題欄',}},onLoad() {},methods: {//返回onBack() {console.log('點擊返回:');},//刷新onRefresh() {console.log('點擊刷新:');}}}
</script><style lang="less">.content {display: flex;flex-direction: column;height: 100vh;background-color: #f5f5f5;}
</style>
全局注冊(適用高頻組件)
在main.js中注冊,但要注意vue2跟vue3的注冊方式,vue2,使用 Vue.component()
方法全局注冊組件,需要在創建 Vue 實例之前注冊 vue3?使用 app.component()
方法注冊(通過 createSSRApp 創建的 app 實例),需要在 createApp
函數內部注冊
// main.js
import titlebar from '@/components/titlebar.vue'
import App from './App'// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'// Vue2 全局組件注冊
Vue.component('titlebar', titlebar)Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({...App
})
app.$mount()
// #endif// #ifdef VUE3
import {createSSRApp
} from 'vue'export function createApp() {const app = createSSRApp(App)// Vue3 全局組件注冊app.component('titlebar', titlebar)return {app}
}
// #endif
三、組件通信
父 -- 子??
通過props傳值:
父 index.vue中
data() {return {pageTitle: '自定義標題欄',}
},
子自定義組件titlebar.vue
props: {title: {type: String,default: '默認標題'},showBack: {type: Boolean,default: true},showRefresh: { type: Boolean,default: false},
},
子-- 父
$emit 觸發
子自定義組件 titlebar.vue
methods: {// 添加 handleBack 方法handleBack() {this.$emit('back'); // 觸發父組件的 @back 事件},// 添加 handleRefresh 方法handleRefresh() {this.$emit('refresh'); // 觸發父組件的 @refresh 事件}}
父index.vue中
methods: {//返回onBack() {console.log('點擊返回:');},//刷新onRefresh() {console.log('點擊刷新:');}
}
四 總結
如果對你有所幫助的話,不妨 點贊收藏
如果你有什么疑問的話,不妨 評論私信
青山不改,綠水長流 ,有緣江湖再見 ~