Button 按钮
17:06说明
以 uni-app 原生 button 为基础二次封装,内置六套主题色,支持尺寸、形状、镂空、禁用、加载、节流等状态,可选水波纹点击反馈。内容有三种承载方式:text 属性或默认插槽用于纯文字(组件自动着色),content 插槽用于图标与富样式混排(插槽内文字需自行设置颜色,App 端样式不继承)。
兼容性
| 平台 | 支持情况 |
|---|---|
| App | ✅ 支持(水波纹 ripple 不支持,开启时自动退回按压深色反馈) |
| H5 | ✅ 支持 |
| 微信小程序 | ✅ 支持(open-type 开放能力、form-type 表单属性仅小程序生效) |
示例
基础用法
默认 default 主题,点击触发 click 事件。
查看源码
<template>
<view class="btn-wrap">
<!-- 纯文字用 text 属性传入,组件自动着色(App 端也可正常显示) -->
<ux-button text="普通按钮" @click="onClick" />
</view>
</template>
<script setup lang="uts">
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
/* 按钮默认在块级容器中全宽居中,如需收缩靠左排列用 flex 容器包裹 */
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
</style>主题类型 type
支持 default / primary / success / error / warning / info 六种主题。
查看源码
<template>
<view class="btn-grid">
<ux-button v-for="(item, index) in typeList" :key="index" :type="item.type" :text="item.label" custom-class="btn-grid-item" @click="onClick" />
</view>
</template>
<script setup lang="uts">
const typeList = [
{ type: 'default', label: 'default' },
{ type: 'primary', label: 'primary' },
{ type: 'success', label: 'success' },
{ type: 'error', label: 'error' },
{ type: 'warning', label: 'warning' },
{ type: 'info', label: 'info' }
];
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.btn-grid-item {
width: 30%;
margin-bottom: 12px;
}
</style>镂空 plain
plain=true 时背景透明,仅显示边框和文字。
查看源码
<template>
<view class="btn-grid">
<ux-button v-for="(item, index) in typeList" :key="index" :type="item.type" :text="item.label" plain custom-class="btn-grid-item" @click="onClick" />
</view>
</template>
<script setup lang="uts">
const typeList = [
{ type: 'default', label: 'default' },
{ type: 'primary', label: 'primary' },
{ type: 'success', label: 'success' },
{ type: 'error', label: 'error' },
{ type: 'warning', label: 'warning' },
{ type: 'info', label: 'info' }
];
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
}
.btn-grid-item {
width: 30%;
margin-bottom: 12px;
}
</style>尺寸大小 size
支持 large / default / small 三种尺寸。
查看源码
<template>
<view class="btn-stack">
<ux-button v-for="(item, index) in sizeList" :key="index" :size="item.size" type="primary" :text="item.label" custom-class="btn-stack-item" @click="onClick" />
</view>
</template>
<script setup lang="uts">
const sizeList = [
{ size: 'large', label: 'large' },
{ size: 'default', label: 'default' },
{ size: 'small', label: 'small' }
];
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-stack {
display: flex;
flex-direction: column;
align-items: flex-start;
}
.btn-stack-item {
margin-bottom: 12px;
}
</style>按钮形状 shape
shape="square" 小圆角(4px,默认),shape="round" 胶囊,shape="circle" 正圆(需宽高相等,示例只放图标)。
查看源码
<template>
<view class="btn-wrap">
<ux-button shape="square" type="primary" text="小圆角" custom-class="btn-item" @click="onClick" />
<ux-button shape="round" type="primary" text="胶囊" custom-class="btn-item" @click="onClick" />
<!-- circle 为正圆(需宽高相等),故只放图标;带文字会撑成椭圆 -->
<ux-button shape="circle" type="primary" icon="star" custom-class="btn-item" @click="onClick" />
</view>
</template>
<script setup lang="uts">
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
</style>自定义圆角 border-radius
border-radius 优先级高于 shape 预设,可定制任意圆角值(单位px);传 0 即为真直角。
查看源码
<template>
<view class="btn-wrap">
<!-- border-radius(单位px)优先级高于 shape 预设,可定制任意圆角;传 0 即为真直角 -->
<ux-button shape="square" :border-radius="0" type="primary" text="直角 0" custom-class="btn-item" @click="onClick" />
<ux-button :border-radius="4" type="primary" text="圆角 4" custom-class="btn-item" @click="onClick" />
<ux-button :border-radius="12" type="error" plain text="圆角 12" custom-class="btn-item" @click="onClick" />
<ux-button :border-radius="24" type="success" text="圆角 24" custom-class="btn-item" @click="onClick" />
</view>
</template>
<script setup lang="uts">
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
</style>水波纹 ripple
ripple=true 开启点击水波纹效果,ripple-bg-color 自定义波纹颜色。
查看源码
<template>
<view class="btn-wrap">
<ux-button ripple type="primary" text="水波纹" custom-class="btn-item" @click="onClick" />
<ux-button ripple ripple-bg-color="rgba(255, 255, 255, 0.3)" type="error" text="水波纹" custom-class="btn-item" @click="onClick" />
</view>
</template>
<script setup lang="uts">
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
</style>App 端不支持水波纹
App 端 UCSS 无 transform/transition 动画,开启 ripple 时会自动退回按压深色反馈;H5 / 微信小程序可用。
细边框 hair-line
hair-line=false 关闭细边框,使用粗边框。
查看源码
<template>
<view class="btn-wrap">
<ux-button type="default" text="细边框" custom-class="btn-item" @click="onClick" />
<ux-button :hair-line="false" type="default" text="粗边框" custom-class="btn-item" @click="onClick" />
</view>
</template>
<script setup lang="uts">
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
</style>加载中 loading
loading=true 显示加载状态,按钮不可点击。
查看源码
<template>
<view class="btn-wrap">
<ux-button loading type="primary" text="默认文案" loading-text="加载中" custom-class="btn-item" />
<ux-button loading type="success" text="默认文案" loading-text="加载中" custom-class="btn-item" />
</view>
<!-- 加载图标大小 loading-size(单位px,默认按按钮尺寸自动匹配) -->
<view class="btn-wrap">
<ux-button loading type="warning" text="默认文案" loading-text="加载中" loading-size="20" custom-class="btn-item" />
</view>
</template>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
</style>禁用 disabled
disabled=true 时按钮置灰不可点击;彩色实心(primary/success/error/warning)隐藏边框,default/info/镂空保留细边框。
查看源码
<template>
<view class="btn-wrap">
<ux-button disabled type="primary" text="禁用按钮" custom-class="btn-item" />
<ux-button disabled plain type="primary" text="禁用镂空" custom-class="btn-item" />
</view>
<!-- 彩色实心(primary/success/error/warning)禁用时隐藏边框;default/info/镂空保留细边框 -->
<view class="btn-wrap">
<ux-button disabled type="default" text="禁用按钮" custom-class="btn-item" />
<ux-button disabled type="info" text="禁用按钮" custom-class="btn-item" />
<ux-button disabled plain type="success" text="禁用镂空" custom-class="btn-item" />
</view>
</template>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
</style>图标按钮 icon
icon 指定图标,icon-size 控制大小,icon-color 控制颜色(默认跟随文字色)。
查看源码
<template>
<view class="btn-wrap">
<ux-button type="primary" icon="star" text="图标按钮" custom-class="btn-item" @click="onClick" />
<ux-button type="error" plain icon="heart" text="图标按钮" custom-class="btn-item" @click="onClick" />
<ux-button type="default" icon="account" icon-color="#2979ff" text="自定义图标色" custom-class="btn-item" @click="onClick" />
</view>
<!-- 仅图标:不传插槽内容则只显示图标,可配合 shape 组成各形态 -->
<view class="btn-wrap btn-icon-row">
<ux-button shape="round" icon="star" type="primary" custom-class="btn-item" @click="onClick" />
<ux-button shape="round" plain icon="heart" type="error" custom-class="btn-item" @click="onClick" />
<ux-button icon="search" type="success" custom-class="btn-item" @click="onClick" />
<ux-button plain icon="close" type="default" custom-class="btn-item" @click="onClick" />
</view>
<!-- 图标大小 icon-size 与垂直偏移 icon-top(单位px,正数向上) -->
<view class="btn-wrap btn-icon-row">
<ux-button type="primary" icon="star" icon-size="20" text="大号图标" custom-class="btn-item" @click="onClick" />
<ux-button type="primary" icon="star" icon-size="26" :icon-top="2" text="大号图标" custom-class="btn-item" @click="onClick" />
</view>
</template>
<script setup lang="uts">
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
.btn-icon-row {
margin-top: 8px;
}
</style>自定义内容 slot
纯文字用 text 或默认插槽(自动着色);富自定义内容用 content 插槽,内层文字需自行设 color(App 端样式不继承)。
查看源码
<template>
<view class="btn-wrap">
<!-- text 属性:纯文字,组件自动着色 -->
<ux-button type="primary" text="text 属性" custom-class="btn-item" @click="onClick" />
<!-- 特色示例:content 插槽富拼装(保留 icon/loading)—— 促销售价"大号加粗价格 + 白底省 ¥100 徽标",
展示纯文字传达不了的混排能力;页面自定义 class 设色 -->
<ux-button type="error" custom-class="btn-item" @click="onClick">
<template #content>
<text class="slot-price">¥299</text>
<text class="slot-badge">省 ¥100</text>
</template>
</ux-button>
</view>
</template>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
/* 特色插槽:促销售价——大号加粗白字价格 */
.slot-price {
color: #ffffff;
font-size: 20px;
font-weight: bold;
}
/* 特色插槽:促销徽标——白底半透明胶囊 + 深红字 */
.slot-badge {
margin-left: 8px;
padding: 0 8px;
border-radius: 10px;
background-color: rgba(255, 255, 255, 0.92);
color: #ee4d38;
font-size: 12px;
line-height: 20px;
}
</style>占满一行 block
block=true 时按钮占满整行宽度。
查看源码
<template>
<view class="btn-stack">
<ux-button block type="primary" icon="star" text="占满一行的按钮" custom-class="btn-stack-item" @click="onClick" />
<ux-button block type="success" plain text="占满一行的按钮" custom-class="btn-stack-item" @click="onClick" />
</view>
</template>
<script setup lang="uts">
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-stack {
display: flex;
flex-direction: column;
}
.btn-stack-item {
margin-bottom: 12px;
}
</style>节流 throttle-time
throttle-time 指定点击节流间隔(单位毫秒),该间隔内的连击只触发一次。
查看源码
<template>
<view class="btn-wrap">
<!-- throttle-time=毫秒:不到该间隔的连击只生效一次,右侧按钮在快速连点时会明显丢次数 -->
<ux-button type="primary" text="无节流" custom-class="btn-item" @click="onNormalTap" />
<ux-button type="error" throttle-time="1000" text="节流 1s" custom-class="btn-item" @click="onTap" />
</view>
</template>
<script setup lang="uts">
const normalCount = ref(0);
const throttledCount = ref(0);
function onNormalTap(): void {
normalCount.value++;
uni.showToast({ title: `未节流:${normalCount.value} 次`, icon: 'none' });
}
function onTap(): void {
throttledCount.value++;
uni.showToast({ title: `节流 1s:${throttledCount.value} 次`, icon: 'none' });
}
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
.btn-item {
margin-right: 12px;
margin-bottom: 12px;
}
</style>自定义样式 custom-style
通过 custom-style 覆盖按钮样式,完全自定义场景下按压反馈(hover/pressing)同样交由样式接管,组件不干预。
查看源码
<template>
<view class="btn-wrap">
<!-- 完全自定义场景(黑底白字)组件无法自动推断文字色,用时须在插槽内层显式设 color -->
<ux-button type="default" :custom-style="customStyle" custom-class="btn-item" @click="onClick">
<text :style="slotTextStyle">自定义样式</text>
</ux-button>
</view>
</template>
<script setup lang="uts">
import { createStyle } from '@/uni_modules/uview-pro-x';
const customStyle = computed((): UTSJSONObject => {
const style = createStyle();
style['backgroundColor'] = '#000000';
style['color'] = '#ffffff';
return style;
});
const slotTextStyle = computed((): UTSJSONObject => {
const style = createStyle();
style['color'] = '#ffffff';
return style;
});
function onClick(): void {
uni.showToast({ title: '点击了按钮', icon: 'none' });
}
</script>
<style scoped>
.btn-wrap {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
</style>API
Props
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|---|---|---|---|---|
customStyle | 自定义根节点样式 | string | UTSJSONObject | - | - |
customClass | 自定义根节点样式类 | string | '' | - |
text | 按钮文本:纯文字用 text 传入或写默认插槽均可,组件自动包带色 text(App 文字颜色已显式处理); 富内容(图标+文字混排、富样式)用 content 插槽,使用者自行控制内层文字颜色 | string | '' | - |
icon | 图标名称,见 ux-icon 图标集,loading 时自动隐藏 | string | '' | - |
iconSize | 图标大小,单位px,不传时按按钮尺寸自动匹配 | string | number | '' | - |
iconColor | 图标颜色,不传时跟随按钮文字色 | string | '' | - |
iconTop | 图标垂直偏移,单位px,正数向上 | number | 0 | - |
block | 是否占满一行 | boolean | false | - |
hairLine | 是否细边框 | boolean | true | - |
type | 按钮的预置样式,default,primary,success,error,warning,info | ButtonType | 'default' | - |
size | 按钮尺寸,large,default,small | ButtonSize | 'default' | - |
shape | 按钮形状:square-小圆角 4px(默认),round-胶囊,circle-正圆;直角请传 border-radius=0 | ButtonShape | 'square' | - |
borderRadius | 自定义圆角值,单位px,优先级高于 shape 预设;默认 '' 表示未设置(传 0 则显式表达真直角) | string | number | '' | - |
plain | 按钮是否镂空 | boolean | false | - |
disabled | 是否禁止状态 | boolean | false | - |
loading | 是否加载中 | boolean | false | - |
loadingText | 加载中显示的文案,不传时沿用按钮文本 | string | '' | - |
loadingSize | 加载图标的大小,单位px,不传时按按钮尺寸自动匹配 | string | number | '' | - |
scope | 支付宝小程序,当 open-type 为 getAuthorize 时有效 | ButtonScope | '' | - |
openType | 开放能力,详见 uni-app button 组件开放能力说明 | ButtonOpenType | '' | - |
formType | 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件 | ButtonFormType | '' | - |
appParameter | 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 | string | '' | - |
hoverStopPropagation | 指定是否阻止本节点的祖先节点出现点击态,微信小程序有效 | boolean | false | - |
lang | 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。只微信小程序有效 | string | 'en' | - |
sessionFrom | 会话来源,open-type="contact"时有效。只微信小程序有效 | string | '' | - |
sendMessageTitle | 会话内消息卡片标题,open-type="contact"时有效 | string | '' | - |
sendMessagePath | 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 | string | '' | - |
sendMessageImg | 会话内消息卡片图片,open-type="contact"时有效 | string | '' | - |
showMessageCard | 是否显示会话内消息卡片,open-type="contact"时有效 | boolean | false | - |
rippleBgColor | 水波纹的背景颜色 | string | '' | - |
ripple | 是否开启水波纹效果 | boolean | false | - |
hoverClass | 按下的类名 | string | '' | - |
dataName | 额外传参参数,用于小程序的data-xxx属性,通过target.dataset.name获取 | string | '' | - |
throttleTime | 节流,一定时间内只能触发一次 | string | number | 0 | - |
hoverStartTime | 按住后多久出现点击态,单位毫秒 | string | number | 20 | - |
hoverStayTime | 手指松开后点击态保留时间,单位毫秒 | string | number | 150 | - |
Events
| 事件名 | 说明 | 回调参数 | 版本 |
|---|---|---|---|
click | 按钮点击 | event: UniEvent | - |
getuserinfo | 获取用户信息回调,detail 中值同 uni.getUserInfo | event: UniEvent | - |
contact | 客服消息回调 | event: UniEvent | - |
getphonenumber | open-type=getPhoneNumber 时有效 | event: UniEvent | - |
error | 使用开放能力发生错误时回调 | event: UniEvent | - |
launchapp | 打开 APP 成功回调 | event: UniEvent | - |
opensetting | 打开授权设置页并关闭后回调 | event: UniEvent | - |
chooseavatar | 头像选择回调 | event: UniEvent | - |
agreeprivacyauthorization | 用户点击允许授权回调 | event: UniEvent | - |
Slots
| 插槽名 | 说明 | 版本 |
|---|---|---|
default | 按钮纯文字内容,组件自动包在带色 text 内并着色(App/H5/小程序到齐),纯文字直接用默认插槽或 text 属性 | - |
content | 完全自定义按钮文字区(图标/view/富样式混排),原样放置、保留 icon 与 loading,插槽内文字需自行设置 color(App 端样式不继承) | - |
注意事项
- 纯文字优先用
text属性,组件按type自动着色,无需手动处理文字颜色;写默认插槽亦可,组件会自动包一层带色text。 - 富内容用
content插槽:App 端样式不继承,插槽内的文字须显式设置color。 - 定制根节点样式(间距、宽高等)用
custom-class而非页面原生class;ux-button已注册externalClasses: ['custom-class'],该机制在小程序隔离策略 2.0 下也能把页面类穿透进组件生效。 border-radius优先级高于shape预设,可定制任意圆角,传0即为真直角(直角不是shape档位)。shape="circle"为正圆,需宽高相等,带文字会撑成椭圆;与block同传时自动降级为round。disabled/loading状态下的点击会被组件内部守卫拦截,不触发click;彩色实心类型(primary/success/error/warning)禁用时隐藏边框。loading时icon自动隐藏,仅保留加载图标与文案;App 端原生 loading 图标固定黑色,组件改用ux-loading+ 文案实现。- 水波纹
ripple仅 H5 / 微信小程序支持,App 端开启时退回按压深色反馈。 open-type(开放能力)/form-type(表单)等属性仅微信小程序生效,App / H5 端忽略。throttle-time为点击节流间隔(毫秒),间隔内的连续点击只触发一次。