Skip to content

n-float-panel 浮动面板 ​

平台兼容性 ​

App-Android App-iOS App-Harmony Web 微信小程序
✓ ✓ ✓ ✓ ✓

使用说明 ​

常驻底部的可拖拽浮动面板(bottom-sheet):拖动头部或内容区在锚点档位间切换可见高度,松手吸附最近锚点;支持多锚点、遮罩、底部安全区与内容滚动,常用于筛选面板、详情面板与快捷操作面板。

html
<template>
	<n-float-panel :anchors="[200, 600]">
		<scroll-view direction="vertical" style="flex: 1">
			<view v-for="i in 20" :key="i" class="list-item">
				<text class="list-text">列表项 {{ i }}</text>
			</view>
		</scroll-view>
	</n-float-panel>
</template>

锚点用面板的可见高度(px)描述:anchors="[200, 600]" 表示面板初始露出 200px、向上拖动展开到 600px。面板本体始终以 height(默认 600)布局内容,收展通过整体下移完成,内容不会被压扁或重排。锚点为 0 时面板完全收起(触摸不可达),再次展开用实例方法 toAnchor。

内容滚动:内容区放 scroll-view(direction="vertical" + flex: 1)即可滚动浏览;此时面板拖动走头部把手,两者互不干扰。若内容不需要滚动(如固定操作区),传 :scrollable="false" 让拖内容也能拖面板。

跳转锚点:

html
<script setup lang="uts">
	import { ref } from "vue";

	const panel = ref<NFloatPanelComponentPublicInstance | null>(null);
	function expand(): void {
		panel.value?.toAnchor(1);
	}
</script>

遮罩:overlay 显示遮罩层(层级在面板之下),close-on-click-overlay 点击遮罩收回面板到最小锚点。

实现说明(机制对照) ​

机制 参考做法 本库做法 分歧理由
收展实现 参考以面板高度动画驱动 面板本体高度固定 = height,translateY 下移收起 内容按完整高度布局不被压扁,展开收起过程内容零重排(bottom-sheet 标准做法)
锚点类型 文档称锚点支持像素或百分比 只收 px(number[]) 百分比的类型形态无法核实(参考源加密),px 语义明确,百分比由使用者换算
内容滚动与拖动竞争 两开关(contentDraggable/scrollable)叠加时的手势竞争语义无法核实(源码加密) scrollable 为 true 时内容区手势交还滚动容器(拖面板走头部);false 且 contentDraggable 开启时拖内容即拖面板 手势竞争必须有确定语义;该模型与参考官方示例行为一致(scroll-view 列表滚动正常、「仅头部拖拽」示例成立)
点击遮罩的「关闭」 文档描述点击遮罩关闭面板,未定义关闭后的状态(无 visible/收起 API) 收回面板到最小锚点并发 change 面板无常驻显隐 API,收回最小锚点是唯一自洽落地;无法核实项如实标注
change 参数 文档未给出参数形态 { index, height }(落定锚点下标与可见高度) 从使用者视角补全;参考源加密无法核对
底色 默认硬编码白色 bgColor 空值走主题背景色(深浅自动),显式传值覆盖 库内主题一致性
自由悬浮容器(参考一) 任意方向拖拽 + 边缘吸附的悬浮球形态 不收录 悬浮球场景由悬浮按钮组件的 free 拖拽模式承担,面板形态不适用吸边/尺寸语义
网格排序拖拽(参考三) 九宫格长按排序 + 删除菜单 不收录 排序功能由拖拽排序组件承担,与本组件(浮动面板)形态不同

API ​

属性 ​

属性 类型 默认值 说明
height number 600 面板本体最大高度(px);锚点值不得超过该值(超出按该值处理)
anchors number[] [] 锚点可见高度数组(px,升序),如 [200, 600];空数组时按 [height] 单锚点处理
default-anchor number 0 初始锚点下标,越界时钳制到有效范围
duration number 300 锚点切换过渡时长(ms);0 为无过渡直接跳转
z-index number 1000 面板层级;遮罩层级为该值减 10
bg-color string "" 面板底色;空值使用主题背景色(深浅模式自动切换),显式传入时覆盖
safe-area-inset-bottom boolean true 是否在面板内底部垫底部安全区高度(小白条 / 手势条机型)
content-draggable boolean true 内容区触摸是否可拖动面板;内容为滚动列表时保持 scrollable 开启(内容滚动优先,拖面板走头部)
scrollable boolean true 内容是否可滚动:true 时内容区手势交还滚动容器;false 且 content-draggable 开启时拖内容即拖面板
overlay boolean false 是否显示遮罩层
overlay-opacity number 0.35 遮罩透明度(0~1)
overlay-fade boolean true 遮罩显隐是否启用淡入淡出过渡
close-on-click-overlay boolean false 点击遮罩是否收回面板到最小锚点
custom-class string "" 组件根节点类名
custom-style string "" 组件根节点行内样式

事件 ​

事件 参数 说明
change (detail: { index: number, height: number }) 面板落定锚点变化时触发(拖动落锚、toAnchor、遮罩收回),index 为锚点下标、height 为可见高度
move (detail: { height: number }) 面板拖动中实时触发,height 为当前可见高度

方法 ​

方法 签名 说明
toAnchor (index: number) => void 跳转到指定锚点(下标越界时钳制),带过渡并发 change 事件

插槽 ​

名称 参数 说明
handle — 头部拖拽区内容,覆盖默认拖拽指示条;触摸绑定由组件承载
default — 面板主体内容;滚动内容放 scroll-view(direction="vertical" + flex: 1)

记录 · 思考 · 创作