import { throttle } from '@src/utils/util'; Component({ options: { multipleSlots: true, addGlobalClass: true, }, externalClasses: ['capsule-class', 'thumb-class', 'title-class', 'icon-class'], properties: { fixed: Boolean, placeholder: { type: Boolean, value: false, }, background: { type: String, value: '#fff', }, title: String, titleColor: String, titlePosition: { type: String, value: 'center', }, hiddenIcon: { type: Boolean, value: false, }, hiddenBack: { type: Boolean, value: false, }, hiddenHome: { type: Boolean, value: false, }, homeUrl: { type: String, value: '/pages/home/index', }, delta: { type: Number, value: 1, }, bufferHeight: { type: Number, value: 44, }, bufferBackground: String, }, data: { capsuleBarStyle: '', opacity: 1, navBarHeight: 66, }, lifetimes: { attached() { this.initCustomButton(); const { titleColor, titlePosition, hiddenBack, hiddenHome } = this.data; const { navBarHeight, capsuleButton } = this.getCapsuleBarInfo(); const capsuleSize = hiddenBack || hiddenHome ? capsuleButton.height : capsuleButton.width; const capsuleLeft = hiddenBack || hiddenHome ? capsuleButton.space + 4 : capsuleButton.space; let capsuleBarStyle = ` --capsule-bar-height:${navBarHeight}px; --capsule-bar-top: ${capsuleButton.top}px; --capsule-bar-right: ${capsuleButton.width + capsuleButton.space}px; --capsule-bar-left: ${capsuleLeft}px; --capsule-bar-icons-width:${capsuleSize}px; --capsule-bar-icons-height:${capsuleButton.height}px;`; if (titleColor) { capsuleBarStyle += `--capsule-bar-title-color: ${titleColor}`; } // 标题居中模式,需要居中一直保持文字居中 if (titlePosition === 'center') { if (hiddenBack || hiddenHome) { capsuleBarStyle += `--capsule-bar-title-margin-left: ${capsuleButton.width / 2}px`; } if (!hiddenBack && !hiddenHome) { capsuleBarStyle += '--capsule-bar-title-margin-left: 0px'; } } this.setData({ capsuleBarStyle, navBarHeight, }); }, }, methods: { initCustomButton() { const { hiddenHome, hiddenBack } = this.data; const pagesStack = getCurrentPages(); if (pagesStack.length < 2 && !hiddenHome) { this.setData({ hiddenHome: false }); } if (pagesStack.length === 1 && !hiddenBack) { this.setData({ hiddenBack: true }); } }, getCapsuleBarInfo() { const { statusBarHeight, screenWidth } = wx.getSystemInfoSync(); const rect = wx.getMenuButtonBoundingClientRect(); // 导航栏高度 = 状态栏到胶囊的间距(胶囊距上距离-状态栏高度) * 2 + 胶囊高度 + 状态栏高度 const navBarHeight = (rect.top - statusBarHeight) * 2 + rect.height + statusBarHeight; // 胶囊距底部间距 // const bottom = rect.top - statusBarHeight; // 胶囊间距(方保持左、右间距一致) const space = screenWidth - rect.right; return { statusBarHeight, navBarHeight, capsuleButton: { ...rect, space, }, }; }, onClickHome() { const url = this.data.homeUrl; if (url) { wx.switchTab({ url }) .catch(() => wx.reLaunch({ url })) .catch((err) => { // tab和非tab方式尝试切换首页均失败,则打印警告 console.warn(err.errMsg); }); } this.triggerEvent('click-left'); }, onClickBack() { const { delta } = this.data; if (delta >= 1 || delta !== -1) { wx.navigateBack({ delta }); } this.triggerEvent('click-right', { delta }); }, onScroll(scrollTop: number) { this.scrollThrottleFunc(this, scrollTop); }, scrollThrottleFunc: throttle((_this, scrollTop: number) => { const outHeight = scrollTop; let opacity: number; if (outHeight <= 0) { opacity = 1; } else if (outHeight >= _this.data.bufferHeight) { opacity = 0; } else { opacity = 1 - outHeight / _this.data.bufferHeight; // ios上小程序navbar高度是44px,android上是48px。 这里统一按照44处理好了,出入不大 } _this.setBarOpacity(opacity); }, 30), setBarOpacity(opacity: number) { this.setData({ opacity }); }, }, });