头部固定(Fixed Header)功能实现
通过主题配置中的 fixHeader 选项,可以切换两种滚动模式:浏览器默认滚动(头部随内容滚动)和固定头部滚动(头部固定,仅内容区域滚动)。
动态组件切换
使用Vue的动态组件 <component :is> 根据配置切换容器:
// 使用computed计算动态组件
const contentWrapperComponent = computed(() => {
return settings.value.fixHeader
? h(ElScrollbar)
: h('div', { class: 'overflow-y-auto h-full' })
})
typescript
<template>
<component :is="contentWrapperComponent">
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
</component>
</template>
vue
头部组件定位处理
当开启 fixHeader 时,头部需要脱离文档流:
// Header组件
const headerStyle = computed(() => {
if (settings.value.fixHeader) {
return {
position: 'absolute',
left: 0,
right: 0,
top: 0,
zIndex: 100,
backgroundColor: 'var(--el-bg-color)'
}
}
return {}
})
typescript
关键细节:
- 使用
absolute而非fixed——fixed在移动端表现不稳定 - 需要设置
z-index确保头部在内容之上 - 需要设置背景色,防止内容透过头部
内容区域的padding补偿
头部使用绝对定位脱离文档流后,内容区域需要添加顶部padding来避免内容被头部遮挡:
<template>
<div :style="{ paddingTop: settings.fixHeader ? '50px' : '' }">
<!-- 内容区域 -->
</div>
</template>
vue
最终效果
| 模式 | 容器 | 头部行为 | 滚动方式 |
|---|---|---|---|
| 默认 | <div> + overflow | 随内容滚动 | 浏览器原生滚动 |
| fixHeader | <el-scrollbar> | 固定在顶部 | 自定义滚动区域 |
keep-alive的包裹方式
keep-alive 需要包裹在动态组件内部:
<component :is="contentWrapperComponent">
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
</component>
vue
这样在两种模式下都能保持页面组件的缓存状态,切换时不会丢失数据。
↑