Skip to content

ActionSheet 操作菜单组件

ActionSheet 组件用于从屏幕底部弹出操作菜单,提供清晰的选项列表供用户选择并返回结果。

适用场景

  • 底部弹出式菜单选择(如分享、删除、操作选项等)
  • 需要从多个选项中选择一个执行特定操作的场景
  • 自定义操作面板(如分享到不同平台)
  • 表单操作的快捷选项(如选择支付方式、配送方式等)

📌平台差异说明

APP(vue)H5微信小程序支付宝小程序

⚠️ 注意事项

注意事项

  1. v-model 绑定

组件使用 v-model 控制显示/隐藏状态:

html
<hy-action-sheet v-model="show" :actions="actions"></hy-action-sheet>
ts
const show = ref(false)
  1. actions 与 panels 的区别
属性用途显示效果
actions文本选项列表纵向排列的文字选项,支持禁用、加载、描述等状态
panels图标面板横向排列的图标+文字,支持多行展示

注意: actionspanels 不能同时使用,优先使用 actions

  1. panels 数据格式

panels 支持一维数组和二维数组:

ts
// 一维数组:单行展示
const panels1 = ref([
    { iconUrl: 'https://xxx.png', name: '微信' },
    { iconUrl: 'https://xxx.png', name: '微博' }
])

// 二维数组:多行展示
const panels2 = ref([
    [
        { iconUrl: 'https://xxx.png', name: '微信' },
        { iconUrl: 'https://xxx.png', name: '微博' }
    ],
    [
        { iconUrl: 'https://xxx.png', name: 'QQ' },
        { iconUrl: 'https://xxx.png', name: '收藏' }
    ]
])
  1. closeOnClickAction 属性

点击选项后是否自动关闭弹窗,默认 true

html
<!-- 点击后不自动关闭 -->
<hy-action-sheet :actions="actions" :close-on-click-action="false"></hy-action-sheet>
  1. select 事件参数

根据使用 actionspanels,select 事件返回的参数不同:

actions 模式:

ts
list = {
    item: { 
        name: '选项1', 
        sub: '', 
        disabled: false, 
        loading: false 
    },  // 选中的选项对象
    index: 0  // 选项索引
}

panels 模式(一维数组):

ts
list = {
    item: { iconUrl: 'https://xxx.png', name: '微信' },  // 选中的面板项
    index: 0  // 索引
}

panels 模式(二维数组):

ts
list = {
    item: { iconUrl: 'https://xxx.png', name: '微信' },  // 选中的面板项
    rowIndex: 0,  // 行索引
    colIndex: 0   // 列索引
}
  1. 样式自定义

组件支持通过 customStylecustomClass 自定义样式:

html
<hy-action-sheet
    v-model="show"
    :actions="actions"
    custom-class="my-action-sheet"
    :custom-style="{ background: '#f5f5f5' }"
></hy-action-sheet>

🏯基本使用示例

基础使用

html
<template>
    <hy-action-sheet v-model="show" :actions="actions" @select="onSelect"></hy-action-sheet>
</template>

<script setup lang="ts">
    import { ref } from 'vue'
    import type { IActionSheetAction } from 'hy-app'

    const show = ref(false)

    const actions = ref<IActionSheetAction[]>([
        { name: '选项1' },
        { name: '选项2' },
        { name: '选项3' }
    ])

    const onSelect = (params) => {
        console.log('选中:', params.item.name)
    }
</script>

带标题

html
<template>
    <hy-action-sheet
        v-model="show"
        :actions="actions"
        title="我是标题"
        @select="onSelect"
    ></hy-action-sheet>
</template>

带取消按钮

html
<template>
    <hy-action-sheet
        v-model="show"
        :actions="actions"
        cancel-text="取消"
        @select="onSelect"
        @cancel="onCancel"
    ></hy-action-sheet>
</template>

<script setup lang="ts">
    const onCancel = () => {
        console.log('点击取消')
    }
</script>

选项状态

html
<template>
    <hy-action-sheet v-model="show" :actions="actions" @select="onSelect"></hy-action-sheet>
</template>

<script setup lang="ts">
    import { ref } from 'vue'
    import type { IActionSheetAction } from '@/package/components/hy-action-sheet/typing'

    const show = ref(false)

    const actions = ref<IActionSheetAction[]>([
        {
            name: '选项1',
            loading: true, // 加载中状态
            color: 'red' // 自定义颜色
        },
        {
            name: '选项2',
            disabled: true // 禁用状态
        },
        {
            name: '选项3',
            sub: '描述信息' // 描述信息
        }
    ])
</script>

自定义面板(一维数组)

html
<template>
    <hy-action-sheet
        v-model="show"
        :panels="panels"
        title="分享给"
        title-align="left"
        @select="onSelect"
    ></hy-action-sheet>
</template>

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

    const show = ref(false)

    const panels = ref([
        {
            iconUrl:
                'https://img12.360buyimg.com/imagetools/jfs/t1/122016/33/6657/1362/5f0692a1E8708d245/e47299e5945a6956.png',
            name: '微信'
        },
        {
            iconUrl:
                'https://img14.360buyimg.com/imagetools/jfs/t1/111572/11/11734/1245/5f0692a1E39d13d21/b35dfe9243bd6c2a.png',
            name: '微博'
        },
        {
            iconUrl:
                'https://img14.360buyimg.com/imagetools/jfs/t1/132639/25/4003/945/5f069336E18778248/fa181913030bed8a.png',
            name: 'QQ'
        }
    ])
</script>

自定义面板(二维数组-多行)

html
<template>
    <hy-action-sheet
        v-model="show"
        :panels="panels"
        title="分享给"
        @select="onSelect"
    ></hy-action-sheet>
</template>
ts
import { ref } from 'vue'

const show = ref(false)

const panels = ref([
    [
        { iconUrl: 'https://xxx.png', name: '微信' },
        { iconUrl: 'https://xxx.png', name: '微博' },
        { iconUrl: 'https://xxx.png', name: 'QQ' },
        { iconUrl: 'https://xxx.png', name: '收藏' }
    ],
    [
        { iconUrl: 'https://xxx.png', name: '微信好友' },
        { iconUrl: 'https://xxx.png', name: '朋友圈' }
    ]
])

const onSelect = (params: any) => {
    console.log('选中:', params.item.name, '行:', params.rowIndex, '列:', params.colIndex)
}

自定义内容插槽

html
<template>
    <hy-action-sheet v-model="show" title="自定义内容">
        <view class="custom-content">
            <text>这里是自定义内容区域</text>
            <hy-button text="确认" @click="show = false"></hy-button>
        </view>
    </hy-action-sheet>
</template>

<style lang="scss" scoped>
    .custom-content {
        padding: 30rpx;
        text-align: center;
    }
</style>

🧪完整示例页面

打开查看示例代码
html
<template>
    <the-root-page>
        <the-cell :list="list" @click="onChange"></the-cell>

        <!-- 基础使用 -->
        <hy-action-sheet
            v-model="list[0].value"
            :actions="actions"
            @select="onClick"
        ></hy-action-sheet>

        <!-- 带标题 -->
        <hy-action-sheet
            v-model="list[1].value"
            :actions="actions"
            title="我是标题"
            @select="onClick"
        ></hy-action-sheet>

        <!-- 带取消 -->
        <hy-action-sheet
            v-model="list[2].value"
            :actions="actions"
            cancel-text="取消"
            @select="onClick"
        ></hy-action-sheet>

        <!-- 加载状态 -->
        <hy-action-sheet
            v-model="list[3].value"
            :actions="actions2"
            @select="onClick"
        ></hy-action-sheet>

        <!-- 自定义面板 -->
        <hy-action-sheet
            v-model="list[4].value"
            :panels="panels"
            title="分享给"
            title-align="left"
            @select="onClick"
        ></hy-action-sheet>
    </the-root-page>
</template>
ts
import { ref, reactive } from 'vue'
import type { IActionSheetAction } from 'hy-app'

const list = reactive([
    { title: '基础使用', value: false },
    { title: '带标题', value: false },
    { title: '带取消', value: false },
    { title: '加载', value: false },
    { title: '自定义面板', value: false }
])

const actions = ref<IActionSheetAction[]>([
    { name: '选项1' },
    { name: '选项2', disabled: true },
    { name: '选项3', sub: '描述信息' }
])

const actions2 = ref<IActionSheetAction[]>([
    { name: '选项1' },
    { name: '选项2', loading: true },
    { name: '选项3' }
])

const panels = ref([
    [
        { iconUrl: 'https://xxx.png', name: '微信' },
        { iconUrl: 'https://xxx.png', name: '微博' },
        { iconUrl: 'https://xxx.png', name: 'QQ' }
    ],
    [
        { iconUrl: 'https://xxx.png', name: '微信好友' },
        { iconUrl: 'https://xxx.png', name: '朋友圈' }
    ]
])

const onChange = (temp: any, index: number) => {
    list[index].value = true
}

const onClick = (temp: any) => {
    uni.showToast({ title: `点击了${temp.item.name}`, icon: 'none' })
}

API

ActionSheet Props

参数说明类型默认值
modelValue是否展示booleanfalse
title标题string-
titleAlign标题文字位置center|left|rightcenter
actions菜单选项IActionSheetAction[][]
panels自定义面板项,可以为字符串数组,也可以为对象数组,如果为二维数组,则为多行展示Array<IActionSheetPanel | IActionSheetPanel[]>[]
cancelText取消按钮的文字,不为空时显示按钮string-
closeOnClickAction点击某个菜单项时是否关闭弹窗booleantrue
closeOnClickOverlay点击遮罩是否允许关闭,见上方文档示例booleantrue
duration弹框动画持续时间number200
zIndex菜单层级number100
round圆角值string | number20
safeAreaInsetBottom是否开启底部安全区适配booleantrue
customStyle自定义外部样式CSSProperties-
customClass自定义外部类名string-
customHeaderClass自定义标题类名string-

Typings

类型说明
ts
interface IActionSheetAction {
    /**
     * 选项名称
     */
    name: string
    /**
     * 描述信息
     */
    sub?: string
    /**
     * 字体颜色
     */
    color?: string
    /**
     * 是否禁用
     */
    disabled?: boolean
    /**
     * 是否加载中
     */
    loading?: boolean
}

interface IActionSheetPanel {
    /**
     * 图片地址
     */
    iconUrl: string
    /**
     * 名称
     */
    name: string
}

interface SelectEventParams {
    /**
     * 选中的内容
     */
    item: any
    /**
     * 选中的横向索引
     */
    rowIndex?: number
    /**
     * 选中的竖列索引
     */
    colIndex?: number
    /**
     * 选中的索引
     */
    index?: number
}

Events

事件名说明回调参数
select点击选项时触发菜单选项或自定义面板一维数组 (item: 选项对象, index: 选项下标),自定义面板二维数组(item: 选项对象, rowIndex: 选项行下标, colIndex 选项列下标)
open弹出层打开时触发-
close弹出层关闭时触发-
cancel点击取消按钮时触发-

Slots

插槽名说明接收值
default面板默认插槽-
13:35