2026/4/6 2:31:56
网站建设
项目流程
组件代码template view classgeneral-nav-bar :style{ height: totalHeight * 2 rpx, paddingTop: statusBarHeight * 2 rpx, opacity: wholeOpacity } view classwallpaper :style{ background: bgColor, opacity: wallpaperOpacity } / !-- 左侧区域 -- view classnav-left slot nameleft up-icon classback-icon v-ifshowBack namearrow-left clickhandleBack / /slot /view !-- 中间标题区域 -- view classnav-center slot nametitle text classdefault-title默认标题/text /slot /view !-- 右侧区域 -- view classnav-right slot nameright / /view /view !-- 额外内容插槽fixed 定位在导航栏下方 -- view classnav-extra v-if$slots.extra :style{ top: totalHeight * 2 rpx } slot nameextra / /view /template script setup import { ref, onMounted, nextTick } from vue const emit defineEmits([height-change]) const props defineProps({ bgColor: { type: String, default: #fff }, showBack: { type: Boolean, default: true }, fallbackUrl: { type: String, default: pages/tabbar/home/home }, wholeOpacity: { type: Number, default: 1, validator: (v) v 0 v 1 }, wallpaperOpacity: { type: Number, default: 1, validator: (v) v 0 v 1 } }) // 内部用 px输出统一转 rpx const statusBarHeight ref(0) const contentHeight ref(44) const totalHeight ref(0) onMounted(() { const info uni.getSystemInfoSync() statusBarHeight.value info.statusBarHeight || 0 // #ifdef MP-WEIXIN // 仅微信小程序可用此 API其他平台走 fallback try { const menuBtn wx.getMenuButtonBoundingClientRect() contentHeight.value menuBtn.height (menuBtn.top - info.statusBarHeight) * 2 } catch { contentHeight.value 44 } // #endif // #ifndef MP-WEIXIN contentHeight.value 44 // #endif totalHeight.value statusBarHeight.value contentHeight.value // 把总高度(px)通知父组件 // 延迟一帧确保 extra 插槽已渲染并可测量 nextTick(() { emitHeight() }) }) const emitHeight () { const toRpx (v) v * 2 emit(height-change, toRpx(totalHeight.value)) } const handleBack () { uni.navigateBack({ fail() { // 没有上一页时跳转到配置的 fallback 页面 uni.switchTab({ url: props.fallbackUrl, fail() { uni.reLaunch({ url: props.fallbackUrl }) } }) } }) } /script style langscss scoped .general-nav-bar { position: fixed; top: 0; left: 0; right: 0; display: flex; align-items: center; justify-content: space-between; box-sizing: border-box; z-index: 999; padding: 0 30rpx; .wallpaper { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .nav-left { position: relative; z-index: 1; width: 120rpx; display: flex; align-items: center; font-size: 26rpx; .back-icon { transition: all 0.2s; :active { transform: scale(0.9); } } } .nav-center { position: relative; z-index: 1; flex: 1; display: flex; align-items: center; justify-content: center; .default-title { font-size: 32rpx; font-weight: 500; color: #333; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } } .nav-right { position: relative; z-index: 1; width: 120rpx; } } .nav-extra { position: fixed; left: 0; right: 0; z-index: 998; } /styleApp.vue:onLaunch: function() { // 初始化全局数据对象 if (!uni.$globalData) { uni.$globalData {}; } const systemInfo uni.getSystemInfoSync(); let statusBarHeight uni.$globalData.statusBarHeight; if (!statusBarHeight) { const pxHeight systemInfo.statusBarHeight || 20; // px 转 rpx statusBarHeight Math.ceil(pxHeight * (750 / systemInfo.screenWidth)); // 存入全局和本地缓存 uni.$globalData.statusBarHeight statusBarHeight; uni.setStorageSync(statusBarHeight, statusBarHeight); } // console.log([${systemInfo.platform}] App Launch - 全局数据:, uni.$globalData); // console.log([${systemInfo.platform}] 状态栏高度rpx:, statusBarHeight); },示例代码template view classpage :style{ paddingTop: 180 rpx, paddingBottom: 0 rpx } !-- 导航栏 -- !-- 整体透明度wholeOpacity 背景透明度wallpaperOpacity -- GeneralNavBar :wallpaperOpacityopacity template #title滚动隐显/template /GeneralNavBar scroll-view styleheight: auto; scroll-y view classlist view classitem v-foritem in 100 :keyitem {{item}} /view /view /scroll-view /view /template script setup import { ref } from vue; import GeneralNavBar from /components/GeneralNavBar.vue; import { onPageScroll, } from dcloudio/uni-app; const opacity ref(0) const scrollThreshold 300 // 滚动多少px后透明度达到1可自定义 onPageScroll((e) { // 微信小程序原生滚动事件e.scrollTop 为滚动距离px const scrollTop e.scrollTop || 0; // 计算透明度滚动距离越近阈值透明度越高0-1之间 opacity.value Math.min(scrollTop / scrollThreshold, 1); }) /script style langscss scoped .page { min-height: 100vh; background-color: #eee; box-sizing: border-box; position: relative; } .list { .item { background-color: aliceblue; text-align: center; margin-bottom: 10rpx; } } /style依赖组件https://www.cnblogs.com/zhangyouwu/p/18561086