# 导航栏
# 技术点
scroll 事件
组件插槽
# 目录结构
└─ components
└─ header # 全局头部组件
├─ header-bar # 通用页面头部
└─ header-scroll-bar # 滚动时可自定义内容
# 功能与实现
header-bar
组件仅作为展示型组件,header-scroll-bar
组件在 header-bar
组件基础上增加了滚动变更内容的功能,以下仅介绍 header-scroll-bar
组件的功能。
# 功能
当页面滚动时,改变 header
背景色与展示内容,如影视详情、影人详情等页面
# 实现
由于组件中没有监听滚动的 api
,滚动高度需要通过页面的 onPageScroll
事件进行监听,将 scrollTop
值传给 header-scroll-bar
组件
# 核心代码
page
页面
<!-- 影人详情页为例 -->
<header-scroll-bar
poster="{{actor.avatar}}"
title="{{actor.name}}"
subtitle="{{actor.name_en}}"
scroll-top="{{ scrollTop }}"
/>
// 页面滚动事件设置 `scrollTop` 值
Page({
data: {
scrollTop: 0
},
onPageScroll({ scrollTop }) {
this.setData({
scrollTop
})
}
})
header-scroll-bar
组件
<view class="header-wrapper">
<!-- 高度占位 -->
<view class="header-shadow" style="height: {{headerBarH}}px;"></view>
<!-- 实际 header -->
<view class="header" style="padding-top: {{statusBarH}}px;height: {{headerBarH}}px;">
<!-- 背景色,滚动时改变透明度 -->
<view class="header-bg {{ isReady && !isTop ? 'is-show': '' }}" style="{{ bgcolorStyle }};{{ opacity }}"></view>
<!-- 返回上一页/返回首页 -->
<view class="back" style="height: {{headerContentH}}px;" bindtap="goBack">
<c-icon class="back-icon {{ isHome ? 'home-icon': '' }}" name="{{ isHome ? 'home-2' : 'back' }}" />
</view>
<!-- 默认展示内容 -->
<view class="category {{ isTop ? 'is-show': '' }}">{{ placeholder }}</view>
<!-- 滚动触发后展示内容 -->
<view class="header-content {{ !isTop ? 'is-show' : '' }}" style="height: {{headerContentH}}px;">
<view class="header-box">
<!-- 海报 -->
<view class="header-poster" wx:if="{{poster}}">
<image mode="heightFix" class="poster" src="{{poster}}" />
</view>
<!-- 内容 -->
<view class="header-info">
<view class="title">{{ title }}</view>
<view class="subtitle" wx:if="{{ subtitle }}">{{ subtitle }}</view>
<!-- 自定义subtitle -->
<slot name="subtitle" wx:else />
</view>
</view>
</view>
</view>
</view>
# JS
文件要点
# 计算 header-bar
高度
header bar
高度可通过 wx.getSystemInfo
方法获取,
wx.getSystemInfo({
success: e => {
const statusBarH = e.statusBarHeight // 状态栏高度 单位 px
const capsule = wx.getMenuButtonBoundingClientRect(); // 胶囊属性
const customBarH = capsule.bottom + capsule.top - e.statusBarHeight; // header bar 高度
const headerContentH = customBarH - statusBarH; // 内容区域高度
}
})
# 是否为首页
通过 getCurrentPages (opens new window) 方法获取页面栈,如果返回的页面栈数组中只有一个元素,则当前页面为首页。
当前页面为首页时,导航栏需显示首页按钮,隐藏返回按钮,点击首页按钮后,调用 wx.reLaunch
方法关闭所有页面,并回到首页。
methods: {
goBack() {
const isHome = getCurrentPages().length === 1;
if (isHome) {
// 首页为 tab 页
wx.switchTab({
url: '/pages/home/index'
})
} else {
// 返回上一页
wx.navigateBack()
}
}
}