框架開源地址:https://gitee.com/yunhaotian/uniapp_mobileFrame
在項目文件下新建 components 文件
使用自定義標題欄需要把pages.json的globalStyle的導航欄樣式取消默認的原生導航欄
官方的自定義導航欄樣式和左邊點擊事件不太符合個人項目,所以對源碼進行了修改,下面是源碼:
<template> <view class="uni-navbar" :class="{'uni-dark':dark}"> <view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': themeBgColor }" class="uni-navbar__content"> <status-bar v-if="statusBar" /> <view :style="{ color: themeColor,backgroundColor: themeBgColor ,height:navbarHeight,'background-image':bgImageColor}" class="uni-navbar__header"> <view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left" :style="{width:leftIconWidth}"> <slot name="left"> <view class="uni-navbar__content_view" v-if="leftIcon.length > 0"> <uni-icons :color="themeColor" :type="leftIcon" size="20" /> </view> <view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length > 0 }" class="uni-navbar-btn-text" v-if="leftText.length"> <text :style="{ color: themeColor, fontSize: '12px' }">{{ leftText }}</text> </view> </slot> </view> <view class="uni-navbar__header-container " @tap="onClickTitle"> <slot> <view class="uni-navbar__header-container-inner" v-if="title.length>0"> <text class="uni-nav-bar-text uni-ellipsis-1" :style="{color: themeColor }">{{ title }}</text> </view> </slot> </view> <view @click="onClickRight" class="uni-navbar__header-btns uni-navbar__header-btns-right" :style="{width:rightIconWidth}"> <slot name="right"> <view v-if="rightIcon.length"> <uni-icons :color="themeColor" :type="rightIcon" size="22" /> </view> <view class="uni-navbar-btn-text" v-if="rightText.length && !rightIcon.length"> <text class="uni-nav-bar-right-text" :style="{ color: themeColor}">{{ rightText }}</text> </view> </slot> </view> </view> </view> <view class="uni-navbar__placeholder" v-if="fixed"> <status-bar v-if="statusBar" /> <view class="uni-navbar__placeholder-view" :style="{ height:navbarHeight}" /> </view> </view> </template> <script> import statusBar from './uni-status-bar.vue'; const getVal = (val) => typeof val === 'number' ? val + 'px' : val; /** * NavBar 自定義導航欄 * @description 導航欄組件,主要用於頭部導航 * @tutorial https://ext.dcloud.net.cn/plugin?id=52 * @property {Boolean} dark 開啟黑暗模式 * @property {String} title 標題文字 * @property {String} leftText 左側按鈕文本 * @property {String} rightText 右側按鈕文本 * @property {String} leftIcon 左側按鈕圖標(圖標類型參考 [Icon 圖標](http://ext.dcloud.net.cn/plugin?id=28) type 屬性) * @property {String} rightIcon 右側按鈕圖標(圖標類型參考 [Icon 圖標](http://ext.dcloud.net.cn/plugin?id=28) type 屬性) * @property {String} color 圖標和文字顏色 * @property {String} backgroundColor 導航欄背景顏色 * @property {String} bgImage 導航欄背景顏色或者背景圖片 * @property {Boolean} fixed = [true|false] 是否固定頂部 * @property {Boolean} statusBar = [true|false] 是否包含狀態欄 * @property {Boolean} shadow = [true|false] 導航欄下是否有陰影 * @event {Function} clickLeft 左側按鈕點擊時觸發 * @event {Function} clickRight 右側按鈕點擊時觸發 * @event {Function} clickTitle 中間標題點擊時觸發 */ export default { name: 'UniNavBar', components: { statusBar }, emits: ['clickLeft', 'clickRight', 'clickTitle'], props: { dark: { type: Boolean, default: false }, title: { type: String, default: '' }, leftText: { type: String, default: '' }, rightText: { type: String, default: '' }, leftIcon: { type: String, default: '' }, rightIcon: { type: String, default: '' }, fixed: { type: [Boolean, String], default: false }, color: { type: String, default: '' }, backgroundColor: { type: String, default: '' }, statusBar: { type: [Boolean, String], default: true }, shadow: { type: [Boolean, String], default: false }, border: { type: [Boolean, String], default: true }, height: { type: [Number, String], default: 44 }, leftWidth: { type: [Number, String], default: 60 }, rightWidth: { type: [Number, String], default: 60 }, bgImage: { type: String, default: '' }, }, computed: { themeBgColor() { if (this.dark) { // 默認值 if (this.backgroundColor) { return this.backgroundColor } else { return this.dark ? '#333' : '#FFF' } } return this.backgroundColor || '#FFF' }, themeColor() { if (this.dark) { // 默認值 if (this.color) { return this.color } else { return this.dark ? '#fff' : '#333' } } return this.color || '#fff' }, bgImageColor() { // 默認值 if (this.bgImage) { return this.bgImage } else { return 'linear-gradient(45deg, #ec008c, #6739b6)' } }, navbarHeight() { return getVal(this.height) }, leftIconWidth() { return getVal(this.leftWidth) }, rightIconWidth() { return getVal(this.rightWidth) } }, mounted() { if (uni.report && this.title !== '') { uni.report('title', this.title) } }, methods: { onClickLeft() { // 把頁面導航欄這邊點擊時間改造成頁面返回事件 // 有些頁面需要返回上幾級頁面,使用本地存儲的pageCurrent值來配合 //默認返回上一頁面 if (uni.getStorageSync('pageCurrent') == '') uni.setStorageSync('pageCurrent', 1) if (uni.getStorageSync('pageCurrent') != 1) { uni.navigateBack({ delta: uni.getStorageSync('pageCurrent') }); uni.setStorageSync('pageCurrent', 1) } else { uni.navigateBack({ delta: 1 }); } // this.$emit("clickLeft"); }, onClickRight() { this.$emit('clickRight'); }, onClickTitle() { this.$emit('clickTitle'); } } }; </script> <style lang="scss" scoped> $nav-height: 44px; .uni-navbar { // box-sizing: border-box; } .uni-nav-bar-text { /* #ifdef APP-PLUS */ font-size: 34rpx; /* #endif */ /* #ifndef APP-PLUS */ font-size: 14px; /* #endif */ } .uni-nav-bar-right-text { font-size: 12px; } .uni-navbar__content { position: relative; // background-color: #fff; // box-sizing: border-box; background-color: transparent; } .uni-navbar__content_view { // box-sizing: border-box; } .uni-navbar-btn-text { /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex-direction: column; justify-content: flex-start; align-items: center; line-height: 12px; } .uni-navbar__header { /* #ifndef APP-NVUE */ display: flex; /* #endif */ padding: 0 10px; flex-direction: row; height: $nav-height; font-size: 12px; } .uni-navbar__header-btns { /* #ifndef APP-NVUE */ overflow: hidden; display: flex; /* #endif */ flex-wrap: nowrap; flex-direction: row; width: 120rpx; // padding: 0 6px; justify-content: center; align-items: center; /* #ifdef H5 */ cursor: pointer; /* #endif */ } .uni-navbar__header-btns-left { /* #ifndef APP-NVUE */ display: flex; /* #endif */ width: 120rpx; justify-content: flex-start; align-items: center; } .uni-navbar__header-btns-right { /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex-direction: row; // width: 150rpx; // padding-right: 30rpx; justify-content: flex-end; align-items: center; } .uni-navbar__header-container { /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex: 1; padding: 0 10px; overflow: hidden; } .uni-navbar__header-container-inner { /* #ifndef APP-NVUE */ display: flex; /* #endif */ flex: 1; flex-direction: row; align-items: center; justify-content: center; font-size: 12px; overflow: hidden; // box-sizing: border-box; } .uni-navbar__placeholder-view { height: $nav-height; } .uni-navbar--fixed { position: fixed; z-index: 998; /* #ifdef H5 */ left: var(--window-left); right: var(--window-right); /* #endif */ /* #ifndef H5 */ left: 0; right: 0; /* #endif */ } .uni-navbar--shadow { box-shadow: 0 1px 6px #ccc; } .uni-navbar--border { border-bottom-width: 1rpx; border-bottom-style: solid; border-bottom-color: #eee; } .uni-ellipsis-1 { overflow: hidden; /* #ifndef APP-NVUE */ white-space: nowrap; text-overflow: ellipsis; /* #endif */ /* #ifdef APP-NVUE */ lines: 1; text-overflow: ellipsis; /* #endif */ } // 暗主題配置 .uni-dark {} </style>
頁面中使用自定義導航欄
<template> <view> <uni-nav-bar leftIcon="arrowleft" :status-bar="true" fixed="true" color="#ffffff" bgImage="linear-gradient(45deg, #ec008c, #6739b6)" title="移動開發框架" /> <uni-nav-bar leftIcon="arrowleft" :status-bar="false" fixed="true" color="#ffffff" bgImage="url('/static/bg.png')" title="移動開發框架" /> <uni-nav-bar leftIcon="arrowleft" :status-bar="false" fixed="true" color="#000000" bgImage="#EEEEEE" title="移動開發框架" /> </view> </template> <script> import uniNavBar from '@/components/uni-nav-bar/uni-nav-bar.vue' export default { data() { return { } }, components: { uniNavBar }, onLoad() { }, methods: { } } </script> <style> </style>
效果: