You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ionic Vue如何实现可任意拖动的悬浮fab按钮

Ionic Vue FAB悬浮按钮拖拽功能实现方案

1. 修改模板代码

将原有ion-fab-button的事件绑定替换为移动端兼容的触摸事件,完整模板如下:

<ion-fab
  vertical="bottom"
  horizontal="end"
  slot="fixed"
  class="utility_fab_button"
  :style="{
    bottom: `${ion_fab_position.bottom}px`,
    right: `${ion_fab_position.right}px`,
  }"
  ref="utility_fab_button_ref"
>
  <ion-fab-button 
    color="dark" 
    @touchstart="dragStart"
    @touchmove.prevent="dragMove"
    @touchend="dragEnd"
  >
    <ion-icon :icon="helpCircleOutline"></ion-icon>
  </ion-fab-button>
  <ion-fab-list side="top">
    <ion-fab-button color="dark" @click="goToWhatsApp($event)">
      <ion-icon :icon="logoWhatsapp"></ion-icon>
    </ion-fab-button>
    <ion-fab-button color="dark" @click="sendEmail($event)">
      <ion-icon :icon="mailOutline"></ion-icon>
    </ion-fab-button>
    <ion-fab-button color="dark" @click="makeCall($event)">
      <ion-icon :icon="callOutline"></ion-icon>
    </ion-fab-button>
  </ion-fab-list>
</ion-fab>

2. 补充逻辑代码

在原有data基础上新增拖拽状态变量,添加对应拖拽处理方法:

export default {
  data() {
    return {
      ion_fab_position: {
        bottom: 10,
        right: 10,
      },
      // 拖拽相关状态
      isDragging: false,
      touchStart: { x: 0, y: 0 },
      fabInitialPos: { bottom: 0, right: 0 },
      // 拖拽阈值,移动超过5px才判定为拖拽,避免误触点击
      dragThreshold: 5
    }
  },
  methods: {
    dragStart(e) {
      const touch = e.touches[0]
      this.touchStart.x = touch.clientX
      this.touchStart.y = touch.clientY
      this.fabInitialPos.bottom = this.ion_fab_position.bottom
      this.fabInitialPos.right = this.ion_fab_position.right
      this.isDragging = false
    },
    dragMove(e) {
      const touch = e.touches[0]
      const deltaX = touch.clientX - this.touchStart.x
      const deltaY = touch.clientY - this.touchStart.y

      if (Math.abs(deltaX) > this.dragThreshold || Math.abs(deltaY) > this.dragThreshold) {
        this.isDragging = true
        // 基于bottom、right定位反向计算偏移量
        let newRight = this.fabInitialPos.right - deltaX
        let newBottom = this.fabInitialPos.bottom - deltaY

        // 边界判断,避免按钮拖出屏幕
        const fabWidth = this.$refs.utility_fab_button_ref.$el.offsetWidth || 56
        const fabHeight = this.$refs.utility_fab_button_ref.$el.offsetHeight || 56
        const screenWidth = window.innerWidth
        const screenHeight = window.innerHeight

        newRight = Math.max(0, Math.min(newRight, screenWidth - fabWidth))
        newBottom = Math.max(0, Math.min(newBottom, screenHeight - fabHeight))

        this.ion_fab_position.right = newRight
        this.ion_fab_position.bottom = newBottom
      }
    },
    dragEnd(e) {
      if (this.isDragging) {
        // 拖拽状态下阻止冒泡,避免触发FAB默认展开逻辑
        e.stopPropagation()
        e.preventDefault()
      }
      this.isDragging = false
    },
    // 保留原有goToWhatsApp、sendEmail、makeCall等方法
  }
}

3. 可选样式优化

添加样式避免拖拽时选中文本:

.utility_fab_button {
  user-select: none;
  -webkit-user-select: none;
}

内容的提问来源于stack exchange,提问作者Sariful

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:57:04