Skip to content

xtf-action-sheet

组件说明

xtf-action-sheet 是从底部弹出的动作面板组件,适用于分享、收藏、删除等轻量级操作列表场景。组件同时支持声明式(v-model:show)和命令式(actionSheetManager)两种调用方式,并提供 service 服务模式实现跨层级全局控制。


基础用法

1. 最简示例

通过 v-model:show 控制显示/隐藏,actions 传入操作列表:

vue
<template>
  <view>
    <xtf-button @click="show = true">打开动作面板</xtf-button>
    <xtf-action-sheet v-model:show="show" :actions="actions" @select="onSelect" />
  </view>
</template>

<script>
export default {
  data() {
    return {
      show: false,
      actions: [
        { label: '分享好友', key: 'share-friend' },
        { label: '分享朋友圈', key: 'share-moment' },
        { label: '收藏', key: 'favorite' }
      ]
    }
  },
  methods: {
    onSelect(payload) {
      console.log('选择了:', payload.action.key)
    }
  }
}
</script>

2. 带标题和描述

通过 titledescription 为面板添加头部说明,配合 danger 标记危险操作:

vue
<template>
  <view>
    <xtf-button @click="show = true">删除确认</xtf-button>
    <xtf-action-sheet
      v-model:show="show"
      title="确认删除?"
      description="此操作不可撤销,请谨慎选择"
      :actions="actions"
      @select="onSelect"
    />
  </view>
</template>

<script>
export default {
  data() {
    return {
      show: false,
      actions: [
        { label: '删除', key: 'delete', danger: true },
        { label: '归档', key: 'archive' }
      ]
    }
  },
  methods: {
    onSelect(payload) {
      uni.showToast({ title: '选择了: ' + payload.action.label, icon: 'none' })
    }
  }
}
</script>

3. 带图标和描述的选项

actions 每项支持 icondescriptiondanger 字段丰富显示效果:

vue
<template>
  <view>
    <xtf-button @click="show = true">分享</xtf-button>
    <xtf-action-sheet
      v-model:show="show"
      title="分享到"
      :actions="shareActions"
      @select="onSelect"
    />
  </view>
</template>

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

4. 布局变体与可视数量

通过 layout 切换四种视觉风格(card / native / compact / system),通过 visibleCount 限制可见项数:

vue
<template>
  <view>
    <view style="display: flex; gap: 16rpx; margin-bottom: 24rpx">
      <xtf-button size="small" @click="openSheet('card')">Card 卡片</xtf-button>
      <xtf-button size="small" @click="openSheet('native')">Native 原生</xtf-button>
      <xtf-button size="small" @click="openSheet('compact')">Compact 紧凑</xtf-button>
    </view>
    <xtf-action-sheet
      v-model:show="show"
      :layout="layout"
      title="选择操作"
      :visible-count="4"
      :actions="actions"
    />
  </view>
</template>

<script>
export default {
  data() {
    return {
      show: false,
      layout: 'card',
      actions: [
        { label: '编辑', key: 'edit' },
        { label: '复制', key: 'copy' },
        { label: '移动', key: 'move' },
        { label: '重命名', key: 'rename' },
        { label: '删除', danger: true, key: 'delete' }
      ]
    }
  },
  methods: {
    openSheet(type) {
      this.layout = type
      this.show = true
    }
  }
}
</script>

5. 关闭拦截与动画

通过 beforeClose 拦截关闭行为(如二次确认),通过 animation 切换弹出动画,通过 closeOnClickAction 控制点击操作项后是否自动关闭:

vue
<template>
  <view>
    <xtf-button @click="show = true">关闭拦截</xtf-button>
    <xtf-action-sheet
      v-model:show="show"
      title="敏感操作"
      :actions="actions"
      :close-on-click-action="false"
      :before-close="beforeClose"
      animation="fade-up"
      @select="onSelect"
    />
  </view>
</template>

<script>
export default {
  data() {
    return {
      show: false,
      actions: [
        { label: '确认删除', key: 'delete', danger: true },
        { label: '仅标记', key: 'flag' }
      ]
    }
  },
  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(payload) {
      console.log('选择了:', payload.action.key)
    }
  }
}
</script>

6. Service 服务模式

通过 service 属性启用全局服务模式,配合 actionSheetManager 可在任意位置命令式控制面板:

vue
<template>
  <view>
    <xtf-action-sheet service />
    <xtf-button @click="showFromAnywhere">从任意位置唤起</xtf-button>
  </view>
</template>

<script>
import { actionSheetManager } from '@/uni_modules/xtf-linkui/libs/action-sheet/action-sheet-manager'

export default {
  methods: {
    showFromAnywhere() {
      actionSheetManager.show({
        title: '确认操作',
        actions: [
          { label: '分享', key: 'share' },
          { label: '删除', danger: true, key: 'delete' }
        ],
        cancelText: '取消'
      })
    }
  }
}
</script>

全部属性

属性类型默认值作用描述适用范围
showBooleanfalse是否显示面板,支持 v-model:show 双向绑定声明式控制显隐
serviceBooleanfalse是否启用全局服务模式,启用后通过 actionSheetManager 控制跨层级全局调用
titleString''面板顶部的标题文字需要面板标题时设置
descriptionString''标题下方的辅助说明文字补充操作背景说明
actionsArray[]操作项数组,每项字段见下方子表核心数据源
cancelTextString''取消按钮文字,默认使用国际化 '取消'自定义取消文案
overlayBooleantrue是否显示遮罩层控制背景遮罩
overlayStyle / overlayBlurString | Object | Array / String | Number'' / 0遮罩自定义样式与背景模糊强度,数字按 rpx 处理原生菜单遮罩
lockScrollBoolean | Stringtrue面板显示时是否锁定背景页面滚动;设为 false 时允许背景滚动页面滚动控制
sideGapString | Number0底部面板左右间距;数字按 rpx 处理,0 为贴边显示面板定位
closeOnClickOverlayBoolean | Stringtrue是否点击遮罩关闭面板防止误关闭时设为 false
closeOnClickActionBooleantrue是否点击操作项后自动关闭面板需要手动控制关闭时机时设为 false
beforeCloseFunctionnull关闭前拦截函数,接收 { type, action, index },返回 false 阻止关闭二次确认、异步校验
roundBooleantrue面板顶部是否圆角控制面板边角样式
zIndexString | Number''面板层级处理遮挡问题时设置
durationString | Number''动画时长(毫秒),animation='none' 时强制为 0调整动画快慢
animationString'slide-up'弹出动画类型:'slide-up' / 'fade' / 'scale' / 'fade-up' / 'none'自定义动效
visibleCountString | Number0可见项数限制,0 为不限制,超出可滚动长列表控制
layoutString'card'布局风格:'card' 卡片 / 'native' 原生 / 'compact' 紧凑 / 'system' 连续原生菜单与独立取消区适配不同 UI 风格
itemClassString | Function''操作项自定义类名,支持函数 (action, index) => className细粒度样式定制
itemStyleString | Object | Function''操作项自定义样式,支持函数 (action, index) => styleObj细粒度样式定制
customClassString''面板整体自定义类名全局样式覆盖
customStyleString | Object''面板整体自定义样式动态样式覆盖
headerClassString''头部区域自定义类名头部样式定制
headerStyleString | Object''头部区域自定义样式头部样式定制
bodyClassString''操作区域自定义类名操作区样式定制
bodyStyleString | Object''操作区域自定义样式操作区样式定制
footerClassString''底部取消区自定义类名取消区样式定制
footerStyleString | Object''底部取消区自定义样式取消区样式定制
titleClassString''标题文字自定义类名标题样式定制
titleStyleString | Object''标题文字自定义样式标题样式定制
descriptionClassString''描述文字自定义类名描述样式定制
descriptionStyleString | Object''描述文字自定义样式描述样式定制
cancelButtonClassString''取消按钮自定义类名取消按钮样式定制
cancelButtonStyleString | Object''取消按钮自定义样式取消按钮样式定制

actions 数组每项支持的字段

字段类型默认值说明
labelString操作项主文案(必填),也兼容 name 字段
descriptionString''操作项辅助描述文字,也兼容 desc 字段
iconString''操作项左侧图标名,支持 xtf-icon 图标库
color / iconColorString''操作项标题与图标颜色;iconColor 优先用于图标
textStyleString | Object | Array''操作项标题的自定义样式
dangerBooleanfalse是否为危险操作项,触发展示红色警告样式
disabledBooleanfalse是否禁用该项,禁用后不可点击且半透明
keyString操作项唯一标识,也兼容 name 字段

事件

事件名称触发时机回调参数参数说明
update:showv-model:show 值变更时触发(value: Boolean)value 为新的显隐状态
open面板开始弹出动画时触发
opened面板弹出动画完成后触发
close面板开始关闭动画时触发($event)原生关闭事件对象
closed面板关闭动画完成后触发($event)原生关闭事件对象
select点击某操作项时触发(disabled 项不触发)(payload: { index: Number, action: Object })index 为点击项索引,action 为原始数据对象
cancel点击取消按钮时触发

事件使用示例

vue
<template>
  <view>
    <xtf-button @click="show = true">打开面板</xtf-button>
    <xtf-action-sheet
      v-model:show="show"
      title="操作"
      :actions="actions"
      @open="onOpen"
      @opened="onOpened"
      @close="onClose"
      @closed="onClosed"
      @select="onSelect"
      @cancel="onCancel"
    />
  </view>
</template>

<script>
export default {
  data() {
    return {
      show: false,
      actions: [
        { label: '编辑', key: 'edit' },
        { label: '删除', key: 'delete', danger: true }
      ]
    }
  },
  methods: {
    onOpen() {
      console.log('面板开始弹出')
    },
    onOpened() {
      console.log('面板弹出完成')
    },
    onClose() {
      console.log('面板开始关闭')
    },
    onClosed() {
      console.log('面板关闭完成')
    },
    onSelect({ index, action }) {
      console.log('选中索引:', index, '数据:', action)
    },
    onCancel() {
      console.log('已取消')
    }
  }
}
</script>

方法

1. open(options) — 实例方法显示面板

通过 ref 调用,在 service 模式下通过 actionSheetManager.show() 打开面板。

注意:仅在 service 模式下有效,需配合 <xtf-action-sheet service /> 使用。

参数类型默认值说明
optionsObject{}面板配置,可包含 title / description / actions / cancelText / layout 等属性

使用示例:

vue
<template>
  <view>
    <xtf-action-sheet ref="sheetRef" service />
    <xtf-button @click="openSheet">打开面板</xtf-button>
  </view>
</template>

<script>
export default {
  methods: {
    openSheet() {
      this.$refs.sheetRef.open({
        title: '选择操作',
        actions: [{ label: '编辑', key: 'edit' }]
      })
    }
  }
}
</script>

2. actionSheetManager.show(options) — 命令式显示

全局命令式 API,需在页面中挂载 <xtf-action-sheet service /> 后方可使用。

引入路径:

js
import { actionSheetManager } from '@/uni_modules/xtf-linkui/libs/action-sheet/action-sheet-manager'
参数类型默认值说明
optionsObject{}面板配置,支持 title / description / actions / cancelText / overlay / closeOnClickOverlay / round / zIndex / duration / animation / visibleCount / layout

返回值Object — 更新后的状态快照

使用示例:

vue
<template>
  <view>
    <xtf-action-sheet service />
    <xtf-button @click="showSheet">显示动作面板</xtf-button>
  </view>
</template>

<script>
import { actionSheetManager } from '@/uni_modules/xtf-linkui/libs/action-sheet/action-sheet-manager'

export default {
  methods: {
    showSheet() {
      actionSheetManager.show({
        title: '分享',
        actions: [
          { label: '微信', key: 'wechat' },
          { label: 'QQ', key: 'qq' }
        ]
      })
    }
  }
}
</script>

3. actionSheetManager.close() — 命令式关闭

关闭当前 service 模式下的面板,状态重置为默认值。

返回值Object — 重置后的状态快照

使用示例:

js
import { actionSheetManager } from '@/uni_modules/xtf-linkui/libs/action-sheet/action-sheet-manager'

actionSheetManager.close()

4. actionSheetManager.update(patch) — 动态更新状态

更新当前面板的状态,可局部更新任意字段,不会重置未指定的字段。

参数类型默认值说明
patchObject必填需要更新的字段对象,如 { show: false, title: '新标题' }

返回值Object — 更新后的状态快照

使用示例:

js
import { actionSheetManager } from '@/uni_modules/xtf-linkui/libs/action-sheet/action-sheet-manager'

actionSheetManager.update({ title: '新标题' })
actionSheetManager.update({ show: false })

5. actionSheetManager.getState() — 获取当前状态

获取 service 模式下的当前完整状态快照。

返回值Object — 包含 show / title / description / actions / cancelText / overlay / closeOnClickOverlay / round / zIndex / duration / animation / visibleCount / layout 全部状态字段

使用示例:

js
import { actionSheetManager } from '@/uni_modules/xtf-linkui/libs/action-sheet/action-sheet-manager'

const state = actionSheetManager.getState()
console.log('当前显示状态:', state.show)
console.log('当前操作列表:', state.actions)

6. actionSheetManager.subscribe(callback) — 订阅状态变化

订阅 service 状态变化,每次状态更新时回调被调用。

参数类型默认值说明
callbackFunction必填(snapshot) => void,每次状态更新时调用

返回值Function — 取消订阅函数,调用后不再接收通知

使用示例:

js
import { actionSheetManager } from '@/uni_modules/xtf-linkui/libs/action-sheet/action-sheet-manager'

const unsubscribe = actionSheetManager.subscribe((state) => {
  console.log('状态变更:', state.show)
})

// 不再需要时取消订阅
unsubscribe()

主题说明

  • 面板背景使用 var(--xtf-popup-bg),毛玻璃效果使用 var(--xtf-action-sheet-blur)
  • card 布局操作项背景使用 var(--xtf-card-bg),继承主题卡片色
  • native 布局背景为 rgba(238, 240, 244, 0.98) 半透明白色,模拟 iOS 原生风格
  • compact 布局为紧凑排列,字号和间距更小
  • 危险项 danger 背景色使用 var(--xtf-color-danger-soft) 淡红色
  • 禁用项 disabled 不透明度为 0.56
  • 操作项边框圆角使用 var(--xtf-radius-xl)
  • 取消按钮区域与操作项间距 18rpx

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

MIT Licensed