Skip to content

xtf-bubble-menu

组件说明

xtf-bubble-menu 是气泡菜单组件,点击或悬浮触发元素后弹出深色气泡面板展示操作列表。支持 8 个弹出方向、箭头指示、图标/图片/描述、关闭拦截和插槽定制,适用于工具栏操作、右键菜单和更多操作等场景。


基础用法

1. 最简示例

通过 actions 传入菜单项,包裹触发元素即可:

vue
<template>
  <xtf-bubble-menu :actions="actions" @select="onSelect">
    <xtf-button size="small">更多操作</xtf-button>
  </xtf-bubble-menu>
</template>

<script>
export default {
  data() {
    return {
      actions: [
        { label: '编辑', key: 'edit', icon: 'edit' },
        { label: '复制', key: 'copy', icon: 'content-copy' },
        { label: '删除', key: 'delete', icon: 'delete', danger: true }
      ]
    }
  },
  methods: {
    onSelect({ action, index }) {
      uni.showToast({ title: '选择了: ' + action.label, icon: 'none' })
    }
  }
}
</script>

2. 弹出方向与箭头

通过 placement 设置弹出方向(8 个方位),通过 arrow 控制是否显示箭头:

vue
<template>
  <view style="display: flex; gap: 24rpx; flex-wrap: wrap">
    <xtf-bubble-menu :actions="actions" placement="bottom-start" @select="onSelect">
      <xtf-button size="small">下左</xtf-button>
    </xtf-bubble-menu>
    <xtf-bubble-menu :actions="actions" placement="bottom" @select="onSelect">
      <xtf-button size="small">下中</xtf-button>
    </xtf-bubble-menu>
    <xtf-bubble-menu :actions="actions" placement="bottom-end" @select="onSelect">
      <xtf-button size="small">下右</xtf-button>
    </xtf-bubble-menu>
    <xtf-bubble-menu :actions="actions" placement="top" :arrow="false" @select="onSelect">
      <xtf-button size="small">上无箭头</xtf-button>
    </xtf-bubble-menu>
  </view>
</template>

<script>
export default {
  data() {
    return {
      actions: [
        { label: '选项一', key: '1' },
        { label: '选项二', key: '2' },
        { label: '选项三', key: '3' }
      ]
    }
  },
  methods: {
    onSelect({ action }) {
      console.log('选择了:', action.key)
    }
  }
}
</script>

3. 带图标、图片和描述

actions 每项支持 iconimagedescription 字段丰富菜单项显示:

vue
<template>
  <xtf-bubble-menu :actions="actions" @select="onSelect">
    <xtf-button size="small">分享</xtf-button>
  </xtf-bubble-menu>
</template>

<script>
export default {
  data() {
    return {
      actions: [
        { label: '微信好友', key: 'wechat', icon: 'wechat', description: '发送给好友' },
        { label: '朋友圈', key: 'moment', icon: 'moment', description: '分享到朋友圈' },
        { label: '复制链接', key: 'copy', icon: 'link', description: '复制到剪贴板' },
        { label: '举报', key: 'report', icon: 'warning', description: '举报不良内容', danger: true }
      ]
    }
  },
  methods: {
    onSelect({ action }) {
      console.log('选择了:', action.key)
    }
  }
}
</script>

4. 手动控制与关闭拦截

通过 v-model:show 手动控制显隐,通过 beforeClose 拦截关闭行为:

vue
<template>
  <view>
    <xtf-bubble-menu
      v-model:show="show"
      trigger="manual"
      :actions="actions"
      :before-close="beforeClose"
      @select="onSelect"
    >
      <xtf-button size="small" @click="show = true">打开菜单</xtf-button>
    </xtf-bubble-menu>
  </view>
</template>

<script>
export default {
  data() {
    return {
      show: false,
      actions: [
        { label: '保存', key: 'save' },
        { label: '删除', key: 'delete', danger: true }
      ]
    }
  },
  methods: {
    async beforeClose({ type }) {
      if (type === 'select') {
        const res = await new Promise((resolve) => {
          uni.showModal({
            title: '确认',
            content: '确认执行此操作?',
            success: (r) => resolve(r.confirm)
          })
        })
        return res
      }
      return true
    },
    onSelect({ action }) {
      console.log('选择了:', action.key)
    }
  }
}
</script>

5. 自定义面板内容

通过 content 插槽完全自定义面板内容:

vue
<template>
  <xtf-bubble-menu :actions="[]" placement="bottom-start">
    <xtf-button size="small">自定义面板</xtf-button>
    <template #content>
      <view style="padding: 24rpx; min-width: 300rpx">
        <xtf-text level="body" style="color: #fff">自定义内容区域</xtf-text>
        <view style="margin-top: 16rpx; display: flex; gap: 12rpx">
          <xtf-button size="small" type="primary" label="确认" />
          <xtf-button size="small" type="light" label="取消" />
        </view>
      </view>
    </template>
  </xtf-bubble-menu>
</template>

全部属性

属性类型默认值作用描述适用范围
showBooleanfalse是否显示面板,支持 v-model:show 双向绑定控制显隐
triggerString'click'触发方式:'click' 点击 / 'hover' 悬浮(H5) / 'manual' 手动控制触发行为
placementString'bottom'弹出方向:'top-start' / 'top' / 'top-end' / 'right' / 'bottom-start' / 'bottom' / 'bottom-end' / 'left'控制弹出位置
actionsArray[]菜单项数组,每项字段见下方子表核心数据源
widthString | Number280面板宽度(rpx)控制面板宽度
maxWidthString | Number''面板最大宽度(rpx)限制最大宽度
offsetString | Number16面板与触发元素的间距(rpx)调整间距
zIndexString | Number12060面板层级处理遮挡问题
transitionDurationString | Number220过渡动画时长(毫秒)调整动画速度
arrowBooleantrue是否显示箭头控制箭头显隐
disabledBooleanfalse是否禁用触发禁用菜单
closeOnClickOutsideBooleantrue是否点击外部关闭防止误关闭
closeOnClickActionBooleantrue是否点击菜单项后自动关闭手动控制关闭
beforeCloseFunctionnull关闭前拦截函数,接收 { type, action, index },返回 false 阻止关闭二次确认
iconSizeString | Number'sm'菜单项图标大小自定义图标大小
showIconBooleantrue是否显示菜单项图标隐藏图标
imageSizeString | Number32菜单项图片大小(rpx)自定义图片大小
showSuffixBooleantrue是否显示后缀箭头图标隐藏后缀图标
suffixIconString'keyboard_arrow_right'后缀图标名自定义后缀图标
customClassString''根元素自定义类名样式覆盖
customStyleString | Object''根元素自定义样式动态样式覆盖
panelClassString''面板自定义类名面板样式定制
panelStyleString | Object''面板自定义样式面板样式定制
listClassString''列表自定义类名列表样式定制
listStyleString | Object''列表自定义样式列表样式定制
itemClassString | Function''菜单项自定义类名,支持函数 (action, index) => className细粒度样式定制
itemStyleString | Object | Function''菜单项自定义样式,支持函数 (action, index) => styleObj细粒度样式定制
iconClassString''图标自定义类名图标样式定制
iconStyleString | Object''图标自定义样式图标样式定制
imageClassString''图片自定义类名图片样式定制
imageStyleString | Object''图片自定义样式图片样式定制
labelClassString''标签自定义类名标签样式定制
labelStyleString | Object''标签自定义样式标签样式定制
suffixIconClassString''后缀图标自定义类名后缀图标样式定制
suffixIconStyleString | Object''后缀图标自定义样式后缀图标样式定制
arrowClassString''箭头自定义类名箭头样式定制
arrowStyleString | Object''箭头自定义样式箭头样式定制

actions 数组每项支持的字段

字段类型默认值说明
labelString菜单项主文案(必填),也兼容 name
keyString唯一标识,也兼容 value
descriptionString''辅助描述文字,也兼容 desc
iconString''左侧图标名
imageString''左侧图片地址,也兼容 img,设置后替代图标
imageModeString'aspectFit'图片填充模式
themeString''图标主题
colorString''图标颜色
dangerBooleanfalse是否为危险操作项,显示红色
disabledBooleanfalse是否禁用
keepOpenBooleanfalse点击后是否保持面板打开
showIconBoolean继承 showIcon单项是否显示图标
showSuffixBoolean继承 showSuffix单项是否显示后缀图标
suffixIconString继承 suffixIcon单项自定义后缀图标

事件

事件名称触发时机回调参数参数说明
update:showv-model:show 值变更时触发(value: Boolean)value 为新的显隐状态
open面板打开时触发
close面板关闭时触发
select点击菜单项时触发(disabled 项不触发)(payload: { index: Number, action: Object })index 为点击项索引,action 为原始数据对象

事件使用示例

vue
<template>
  <xtf-bubble-menu
    v-model:show="show"
    :actions="actions"
    @open="onOpen"
    @close="onClose"
    @select="onSelect"
  >
    <xtf-button label="更多操作" />
  </xtf-bubble-menu>
</template>

<script>
export default {
  data() {
    return { show: false, actions: [{ label: '编辑', key: 'edit' }] }
  },
  methods: {
    onOpen() {
      console.log('菜单打开')
    },
    onClose() {
      console.log('菜单关闭')
    },
    onSelect({ action }) {
      uni.showToast({ title: action.label, icon: 'none' })
    }
  }
}
</script>

插槽

插槽名作用域参数说明
默认插槽菜单触发元素。
content{ actions, select }替换整个菜单面板内容。
item{ action, index }替换单个菜单项。

主题说明

  • 面板背景为 rgba(12, 12, 14, 0.96) 深色半透明
  • 箭头背景与面板一致
  • 面板阴影为 0 18rpx 42rpx rgba(15, 23, 42, 0.28)
  • 菜单项文字颜色为 #ffffff,描述文字为 rgba(255, 255, 255, 0.68)
  • 危险项文字颜色为 #ff8d8d
  • 禁用项不透明度为 0.45
  • 分隔线颜色为 rgba(255, 255, 255, 0.08)
  • 后缀图标颜色为 rgba(255, 255, 255, 0.72)
  • 面板圆角 24rpx,过渡动画使用 var(--xtf-bubble-menu-duration)

如需全局调整主题,请在 xtf-config-provider 或主题配置中覆盖上述 CSS 变量。

MIT Licensed