Skip to content

FloatingPanel 浮动面板

介绍

FloatingPanel 浮动面板是一个浮动在页面底部的面板组件,用户可以通过上下拖动面板来浏览内容。这种交互模式常用于地图导航、音乐播放器等场景,在不离开当前视图的情况下访问更多信息。

核心特性:

  • 拖拽交互 - 支持手势拖拽控制面板高度
  • 锚点吸附 - 支持自定义锚点,释放后自动吸附
  • 平滑动画 - 内置缓动动画,体验流畅
  • 内容滚动 - 内容区域支持独立滚动
  • 安全区域 - 支持底部安全区域适配

基本用法

基础用法

vue
<template>
  <view class="page">
    <view class="content">页面内容</view>
    <wd-floating-panel>
      <view class="panel-content">
        <view v-for="i in 20" :key="i" class="panel-item">
          列表项 {{ i }}
        </view>
      </view>
    </wd-floating-panel>
  </view>
</template>

<style lang="scss" scoped>
.panel-content {
  padding: 32rpx;
}
.panel-item {
  padding: 24rpx 0;
  border-bottom: 1rpx solid #eee;
}
</style>

自定义锚点

通过 anchors 属性设置自定义锚点。

vue
<template>
  <wd-floating-panel :anchors="[100, 300, 500]">
    <view class="panel-content">
      面板内容
    </view>
  </wd-floating-panel>
</template>

受控高度

通过 v-model:height 控制面板高度。

vue
<template>
  <view class="controls">
    <wd-button @click="height = 100">收起</wd-button>
    <wd-button @click="height = 300">中间</wd-button>
    <wd-button @click="height = 500">展开</wd-button>
  </view>
  <wd-floating-panel v-model:height="height" :anchors="[100, 300, 500]">
    <view class="panel-content">
      当前高度: {{ height }}
    </view>
  </wd-floating-panel>
</template>

<script lang="ts" setup>
import { ref } from 'vue'

const height = ref(100)
</script>

监听高度变化

通过 height-change 事件监听高度变化。

vue
<template>
  <wd-floating-panel
    :anchors="[100, 300, 500]"
    @height-change="handleHeightChange"
  >
    <view class="panel-content">面板内容</view>
  </wd-floating-panel>
</template>

<script lang="ts" setup>
const handleHeightChange = ({ height }) => {
  console.log('面板高度变化:', height)
}
</script>

安全区域适配

设置 safe-area-inset-bottom 适配底部安全区域。

vue
<template>
  <wd-floating-panel safe-area-inset-bottom>
    <view class="panel-content">面板内容</view>
  </wd-floating-panel>
</template>

自定义动画时长

通过 duration 设置动画时长。

vue
<template>
  <wd-floating-panel :duration="500">
    <view class="panel-content">面板内容</view>
  </wd-floating-panel>
</template>

禁用内容拖拽

设置 content-draggablefalse,仅允许头部拖拽。

vue
<template>
  <wd-floating-panel :content-draggable="false">
    <view class="panel-content">
      只能通过顶部拖拽条拖拽面板
    </view>
  </wd-floating-panel>
</template>

隐藏滚动条

设置 show-scrollbarfalse 隐藏滚动条。

vue
<template>
  <wd-floating-panel :show-scrollbar="false">
    <view class="panel-content">
      <view v-for="i in 20" :key="i">列表项 {{ i }}</view>
    </view>
  </wd-floating-panel>
</template>

API

Props

参数说明类型默认值
v-model:height面板显示高度number0
anchors自定义锚点数组number[][100, windowHeight * 0.6]
duration动画时长(毫秒)number | string300
content-draggable是否允许内容区域拖拽booleantrue
safe-area-inset-bottom是否设置底部安全距离booleanfalse
show-scrollbar是否显示滚动条booleantrue
custom-class自定义根节点样式类string-
custom-style自定义根节点样式string-

Events

事件名说明回调参数
update:height高度更新时触发height: number
height-change高度变化完成时触发{ height: number }

Slots

名称说明
default面板内容

主题定制

组件提供了以下 CSS 变量用于主题定制:

变量名说明默认值
--wd-floating-panel-z-index面板层级999
--wd-floating-panel-radius面板圆角32rpx
--wd-floating-panel-bg面板背景色#ffffff
--wd-floating-panel-header-height头部高度60rpx
--wd-floating-panel-bar-width拖拽条宽度40rpx
--wd-floating-panel-bar-height拖拽条高度6rpx
--wd-floating-panel-bar-bg拖拽条背景色#c0c4cc
--wd-floating-panel-bar-radius拖拽条圆角3rpx
--wd-floating-panel-content-bg内容区背景色#ffffff

最佳实践

1. 地图导航场景

vue
<template>
  <view class="map-page">
    <!-- 地图区域 -->
    <map class="map" :latitude="latitude" :longitude="longitude" />

    <!-- 浮动面板 -->
    <wd-floating-panel
      :anchors="[150, 400]"
      safe-area-inset-bottom
    >
      <view class="route-info">
        <view class="destination">
          <text class="name">目的地名称</text>
          <text class="distance">3.2公里 · 约15分钟</text>
        </view>
        <view class="actions">
          <wd-button type="primary" block>开始导航</wd-button>
        </view>
        <view class="route-steps">
          <view v-for="step in steps" :key="step.id" class="step">
            {{ step.instruction }}
          </view>
        </view>
      </view>
    </wd-floating-panel>
  </view>
</template>

2. 音乐播放器

vue
<template>
  <view class="music-page">
    <wd-floating-panel
      v-model:height="panelHeight"
      :anchors="[80, 400]"
    >
      <!-- 迷你播放条 -->
      <view v-if="panelHeight <= 100" class="mini-player">
        <image :src="currentSong.cover" class="cover" />
        <view class="info">
          <text class="title">{{ currentSong.title }}</text>
          <text class="artist">{{ currentSong.artist }}</text>
        </view>
        <wd-icon name="play" size="48rpx" @click="togglePlay" />
      </view>

      <!-- 完整播放器 -->
      <view v-else class="full-player">
        <image :src="currentSong.cover" class="cover-large" />
        <text class="title">{{ currentSong.title }}</text>
        <text class="artist">{{ currentSong.artist }}</text>
        <!-- 播放控制 -->
      </view>
    </wd-floating-panel>
  </view>
</template>

3. 商品详情

vue
<template>
  <view class="product-page">
    <image :src="product.image" class="product-image" />

    <wd-floating-panel :anchors="[200, 500]">
      <view class="product-info">
        <view class="price">¥{{ product.price }}</view>
        <view class="title">{{ product.title }}</view>
        <view class="desc">{{ product.description }}</view>

        <view class="specs">
          <text class="label">规格</text>
          <view class="spec-list">
            <view
              v-for="spec in product.specs"
              :key="spec.id"
              class="spec-item"
            >
              {{ spec.name }}
            </view>
          </view>
        </view>

        <wd-button type="primary" block>加入购物车</wd-button>
      </view>
    </wd-floating-panel>
  </view>
</template>

常见问题

1. 面板无法拖动?

检查是否设置了正确的锚点,以及组件是否被其他元素遮挡。

2. 内容滚动与面板拖拽冲突?

组件已经处理了滚动与拖拽的冲突。如果仍有问题,可以尝试设置 content-draggablefalse

3. 如何实现完全收起?

将锚点数组的第一个值设置为 0:

vue
<wd-floating-panel :anchors="[0, 300, 500]">
  ...
</wd-floating-panel>

4. 动画不流畅?

适当增加 duration 值,或检查页面是否有性能问题。

移动端预览