介绍
悬浮按钮,点击可展开扩展按钮。
引入
js
import Fab from 'sard-uniapp/components/fab/fab.vue'
import FabItem from 'sard-uniapp/components/fab-item/fab-item.vue'代码演示
基础使用
设置 item-list 属性配置扩展按钮,监听 select 事件来知晓用户点击了哪个按钮。
vue
<template>
<sar-fab :item-list="itemList" @select="onSelect" />
</template>
<script setup lang="ts">
import { toast, type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const itemList = ref<FabItem[]>([
{ name: '首页', iconFamily: 'demo-icons', icon: 'house-door' },
{ name: '分享好友', iconFamily: 'demo-icons', icon: 'share' },
{ name: '收藏', iconFamily: 'demo-icons', icon: 'star' },
])
const onSelect = (item: FabItem) => {
toast(`选择了: ${item.name}`)
}
</script>vue
<template>
<sar-fab :item-list="itemList" @select="onSelect" />
</template>
<script setup lang="js">
import { toast } from "sard-uniapp";
import { ref } from "vue";
const itemList = ref([
{ name: "\u9996\u9875", iconFamily: "demo-icons", icon: "house-door" },
{ name: "\u5206\u4EAB\u597D\u53CB", iconFamily: "demo-icons", icon: "share" },
{ name: "\u6536\u85CF", iconFamily: "demo-icons", icon: "star" }
]);
const onSelect = (item) => {
toast(`\u9009\u62E9\u4E86: ${item.name}`);
};
</script>自定义颜色
设置 background 属性以及按钮项的 background 自定义背景色。
vue
<template>
<sar-fab
:item-list="itemList"
background="linear-gradient(300deg, rgb(245, 52, 35) 0%, rgb(246, 127, 72) 100%)"
/>
</template>
<script setup lang="ts">
import { type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const itemList = ref<FabItem[]>([
{
name: '首页',
iconFamily: 'demo-icons',
icon: 'house-door',
background: 'rgb(59, 190, 136)',
},
{
name: '分享好友',
iconFamily: 'demo-icons',
icon: 'share',
background: 'rgb(247, 149, 59)',
},
{
name: '收藏',
iconFamily: 'demo-icons',
icon: 'star',
background: 'rgb(52, 147, 240)',
},
])
</script>vue
<template>
<sar-fab
:item-list="itemList"
background="linear-gradient(300deg, rgb(245, 52, 35) 0%, rgb(246, 127, 72) 100%)"
/>
</template>
<script setup lang="js">
import { ref } from "vue";
const itemList = ref([
{
name: "\u9996\u9875",
iconFamily: "demo-icons",
icon: "house-door",
background: "rgb(59, 190, 136)"
},
{
name: "\u5206\u4EAB\u597D\u53CB",
iconFamily: "demo-icons",
icon: "share",
background: "rgb(247, 149, 59)"
},
{
name: "\u6536\u85CF",
iconFamily: "demo-icons",
icon: "star",
background: "rgb(52, 147, 240)"
}
]);
</script>隐藏按钮名称
默认会显示按钮项的 name 属性,可以设置 hide-name 属性进行隐藏。
vue
<template>
<sar-fab :item-list="itemList" hide-name />
</template>
<script setup lang="ts">
import { type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const itemList = ref<FabItem[]>([
{ name: '首页', iconFamily: 'demo-icons', icon: 'house-door' },
{ name: '分享好友', iconFamily: 'demo-icons', icon: 'share' },
{ name: '收藏', iconFamily: 'demo-icons', icon: 'star' },
])
</script>vue
<template>
<sar-fab :item-list="itemList" hide-name />
</template>
<script setup lang="js">
import { ref } from "vue";
const itemList = ref([
{ name: "\u9996\u9875", iconFamily: "demo-icons", icon: "house-door" },
{ name: "\u5206\u4EAB\u597D\u53CB", iconFamily: "demo-icons", icon: "share" },
{ name: "\u6536\u85CF", iconFamily: "demo-icons", icon: "star" }
]);
</script>左上角显示
按钮默认显示在右下角,设置 left 或 top 可以让其显示在左上角。
vue
<template>
<sar-fab :item-list="itemList" top="80px" left="48rpx" />
</template>
<script setup lang="ts">
import { type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const itemList = ref<FabItem[]>([
{ name: '首页', iconFamily: 'demo-icons', icon: 'house-door' },
{ name: '分享好友', iconFamily: 'demo-icons', icon: 'share' },
{ name: '收藏', iconFamily: 'demo-icons', icon: 'star' },
])
</script>vue
<template>
<sar-fab :item-list="itemList" top="80px" left="48rpx" />
</template>
<script setup lang="js">
import { ref } from "vue";
const itemList = ref([
{ name: "\u9996\u9875", iconFamily: "demo-icons", icon: "house-door" },
{ name: "\u5206\u4EAB\u597D\u53CB", iconFamily: "demo-icons", icon: "share" },
{ name: "\u6536\u85CF", iconFamily: "demo-icons", icon: "star" }
]);
</script>右上角显示
按钮默认显示在右下角,设置 top 会将其从底部显示在顶部。
vue
<template>
<sar-fab :item-list="itemList" top="80px" right="48rpx" />
</template>
<script setup lang="ts">
import { type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const itemList = ref<FabItem[]>([
{ name: '首页', iconFamily: 'demo-icons', icon: 'house-door' },
{ name: '分享好友', iconFamily: 'demo-icons', icon: 'share' },
{ name: '收藏', iconFamily: 'demo-icons', icon: 'star' },
])
</script>vue
<template>
<sar-fab :item-list="itemList" top="80px" right="48rpx" />
</template>
<script setup lang="js">
import { ref } from "vue";
const itemList = ref([
{ name: "\u9996\u9875", iconFamily: "demo-icons", icon: "house-door" },
{ name: "\u5206\u4EAB\u597D\u53CB", iconFamily: "demo-icons", icon: "share" },
{ name: "\u6536\u85CF", iconFamily: "demo-icons", icon: "star" }
]);
</script>左下角显示
按钮默认显示在右下角,设置 left 会将其从右边显示在左边。
vue
<template>
<sar-fab :item-list="itemList" left="48rpx" />
</template>
<script setup lang="ts">
import { type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const itemList = ref<FabItem[]>([
{ name: '首页', iconFamily: 'demo-icons', icon: 'house-door' },
{ name: '分享好友', iconFamily: 'demo-icons', icon: 'share' },
{ name: '收藏', iconFamily: 'demo-icons', icon: 'star' },
])
</script>vue
<template>
<sar-fab :item-list="itemList" left="48rpx" />
</template>
<script setup lang="js">
import { ref } from "vue";
const itemList = ref([
{ name: "\u9996\u9875", iconFamily: "demo-icons", icon: "house-door" },
{ name: "\u5206\u4EAB\u597D\u53CB", iconFamily: "demo-icons", icon: "share" },
{ name: "\u6536\u85CF", iconFamily: "demo-icons", icon: "star" }
]);
</script>自定义图标
使用 icon 和 icon-family 可自定义悬浮按钮图标。
vue
<template>
<sar-fab
:item-list="itemList"
icon="list"
visible-icon="close"
icon-family="demo-icons"
/>
</template>
<script setup lang="ts">
import { type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const itemList = ref<FabItem[]>([
{ name: '首页', iconFamily: 'demo-icons', icon: 'house-door' },
{ name: '分享好友', iconFamily: 'demo-icons', icon: 'share' },
{ name: '收藏', iconFamily: 'demo-icons', icon: 'star' },
])
</script>vue
<template>
<sar-fab
:item-list="itemList"
icon="list"
visible-icon="close"
icon-family="demo-icons"
/>
</template>
<script setup lang="js">
import { ref } from "vue";
const itemList = ref([
{ name: "\u9996\u9875", iconFamily: "demo-icons", icon: "house-door" },
{ name: "\u5206\u4EAB\u597D\u53CB", iconFamily: "demo-icons", icon: "share" },
{ name: "\u6536\u85CF", iconFamily: "demo-icons", icon: "star" }
]);
</script>自定义插槽内容 1.24.3+
使用 default 插槽自定义入口按钮内容,使用 list 插槽自定义扩展按钮内容,需要自行循环 FabItem 组件。
vue
<template>
<sar-fab root-style="--sar-fab-item-btn-font-size: 28rpx">
<template #default="{ visible }">
{{ visible ? '关闭' : '打开' }}
</template>
<template #list>
<sar-fab-item
v-for="item in itemList"
:key="item.name"
@click="onClick(item.name)"
>
<text>{{ item.name }}</text>
</sar-fab-item>
</template>
</sar-fab>
</template>
<script setup lang="ts">
import { toast } from 'sard-uniapp'
import { ref } from 'vue'
const itemList = ref([{ name: '首页' }, { name: '分享' }, { name: '收藏' }])
const onClick = (name: string) => {
toast(`选择了: ${name}`)
}
</script>vue
<template>
<sar-fab root-style="--sar-fab-item-btn-font-size: 28rpx">
<template #default="{ visible }">
{{ visible ? '关闭' : '打开' }}
</template>
<template #list>
<sar-fab-item
v-for="item in itemList"
:key="item.name"
@click="onClick(item.name)"
>
<text>{{ item.name }}</text>
</sar-fab-item>
</template>
</sar-fab>
</template>
<script setup lang="js">
import { toast } from "sard-uniapp";
import { ref } from "vue";
const itemList = ref([{ name: "\u9996\u9875" }, { name: "\u5206\u4EAB" }, { name: "\u6536\u85CF" }]);
const onClick = (name) => {
toast(`\u9009\u62E9\u4E86: ${name}`);
};
</script>可拖拽的 1.24.2+
设置 draggable 属性,悬浮按钮展示在右下角,允许在 y 轴方向上下拖拽。
vue
<template>
<sar-fab
:item-list="itemList"
draggable
:navbar-height="navbarHeight"
@select="onSelect"
/>
</template>
<script setup lang="ts">
import { toast, type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const navbarHeight = uni.upx2px(88)
const itemList = ref<FabItem[]>([
{ name: '首页', iconFamily: 'demo-icons', icon: 'house-door' },
{ name: '分享好友', iconFamily: 'demo-icons', icon: 'share' },
{ name: '收藏', iconFamily: 'demo-icons', icon: 'star' },
])
const onSelect = (item: FabItem) => {
toast(`选择了: ${item.name}`)
}
</script>vue
<template>
<sar-fab
:item-list="itemList"
draggable
:navbar-height="navbarHeight"
@select="onSelect"
/>
</template>
<script setup lang="js">
import { toast } from "sard-uniapp";
import { ref } from "vue";
const navbarHeight = uni.upx2px(88);
const itemList = ref([
{ name: "\u9996\u9875", iconFamily: "demo-icons", icon: "house-door" },
{ name: "\u5206\u4EAB\u597D\u53CB", iconFamily: "demo-icons", icon: "share" },
{ name: "\u6536\u85CF", iconFamily: "demo-icons", icon: "star" }
]);
const onSelect = (item) => {
toast(`\u9009\u62E9\u4E86: ${item.name}`);
};
</script>自由拖拽和磁吸 1.24.2+
axis 属性设置允许在 x 或 y 轴方向拖拽,magnet 属性设置松开手指后吸附到指定轴方向的最近一边。
vue
<template>
<sar-fab
:item-list="itemList"
draggable
axis="both"
magnet="x"
:navbar-height="navbarHeight"
@select="onSelect"
/>
</template>
<script setup lang="ts">
import { toast, type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const navbarHeight = uni.upx2px(88)
const itemList = ref<FabItem[]>([
{ name: '首页', iconFamily: 'demo-icons', icon: 'house-door' },
{ name: '分享好友', iconFamily: 'demo-icons', icon: 'share' },
{ name: '收藏', iconFamily: 'demo-icons', icon: 'star' },
])
const onSelect = (item: FabItem) => {
toast(`选择了: ${item.name}`)
}
</script>vue
<template>
<sar-fab
:item-list="itemList"
draggable
axis="both"
magnet="x"
:navbar-height="navbarHeight"
@select="onSelect"
/>
</template>
<script setup lang="js">
import { toast } from "sard-uniapp";
import { ref } from "vue";
const navbarHeight = uni.upx2px(88);
const itemList = ref([
{ name: "\u9996\u9875", iconFamily: "demo-icons", icon: "house-door" },
{ name: "\u5206\u4EAB\u597D\u53CB", iconFamily: "demo-icons", icon: "share" },
{ name: "\u6536\u85CF", iconFamily: "demo-icons", icon: "star" }
]);
const onSelect = (item) => {
toast(`\u9009\u62E9\u4E86: ${item.name}`);
};
</script>双向绑定 1.24.2+
使用 v-model:offset 控制悬浮按钮的位置。
vue
<template>
<sar-fab
:item-list="itemList"
draggable
axis="both"
v-model:offset="offset"
:navbar-height="navbarHeight"
@select="onSelect"
/>
<view class="mt-30 text-center">
<text>x: {{ offset.x.toFixed(0) }}</text>
<text class="ml-20">y: {{ offset.y.toFixed(0) }}</text>
</view>
</template>
<script setup lang="ts">
import { toast, type FabItem } from 'sard-uniapp'
import { ref } from 'vue'
const navbarHeight = uni.upx2px(88)
const itemList = ref<FabItem[]>([
{ name: '首页', iconFamily: 'demo-icons', icon: 'house-door' },
{ name: '分享好友', iconFamily: 'demo-icons', icon: 'share' },
{ name: '收藏', iconFamily: 'demo-icons', icon: 'star' },
])
const onSelect = (item: FabItem) => {
toast(`选择了: ${item.name}`)
}
const offset = ref({
x: 200,
y: 300,
})
</script>vue
<template>
<sar-fab
:item-list="itemList"
draggable
axis="both"
v-model:offset="offset"
:navbar-height="navbarHeight"
@select="onSelect"
/>
<view class="mt-30 text-center">
<text>x: {{ offset.x.toFixed(0) }}</text>
<text class="ml-20">y: {{ offset.y.toFixed(0) }}</text>
</view>
</template>
<script setup lang="js">
import { toast } from "sard-uniapp";
import { ref } from "vue";
const navbarHeight = uni.upx2px(88);
const itemList = ref([
{ name: "\u9996\u9875", iconFamily: "demo-icons", icon: "house-door" },
{ name: "\u5206\u4EAB\u597D\u53CB", iconFamily: "demo-icons", icon: "share" },
{ name: "\u6536\u85CF", iconFamily: "demo-icons", icon: "star" }
]);
const onSelect = (item) => {
toast(`\u9009\u62E9\u4E86: ${item.name}`);
};
const offset = ref({
x: 200,
y: 300
});
</script>API
FabProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| root-class | 组件根元素类名 | string | - |
| root-style | 组件根元素样式 | StyleValue | - |
| top | 设置距离窗口顶部的距离,优先级比 bottom 高 | string | - |
| right | 设置距离窗口右边的距离 | string | - |
| bottom | 设置距离窗口底部的距离 | string | - |
| left | 设置距离窗口左边的距离,优先级比 right 高 | string | - |
| color | 设置按钮图标的颜色 | string | - |
| background | 设置按钮的背景色 | string | - |
| icon | 设置入口按钮的图标 | string | - |
| visible-icon 1.24.3+ | 设置弹出扩展按钮时的入口按钮的图标 | string | - |
| icon-family | 设置入口按钮的图标族 | string | - |
| item-list | 设置扩展按钮 | FabItem[] | [] |
| hide-name | 是否隐藏按钮名称 | boolean | false |
| overlay-closable | 点击遮罩是否隐藏扩展按钮 | boolean | false |
| duration | 扩展按钮显隐动画时长,单位 ms | number | 150 |
| draggable 1.24.2+ | 是否可拖拽 | boolean | false |
| axis 1.24.2+ | 允许拖拽的方向轴 | 'x' | 'y' | 'both' | 'none' | 'y' |
| magnet 1.24.2+ | 吸附到指定轴最近的一边,在拖拽时使用 | 'x' | 'y' | - |
| gap-x 1.24.2+ | 悬浮按钮与窗口左右两边的最小间距,单位为 px,在拖拽时使用 | number | 24 |
| gap-y 1.24.2+ | 悬浮按钮与窗口上下两边的最小间距,单位为 px,在拖拽时使用 | number | 24 |
| offset (v-model) 1.24.2+ | 控制悬浮按钮的位置,在拖拽时使用 | { x: number; y: number } | - |
| navbar-height 1.24.3+ | 自定义顶部导航栏的高度,在拖拽时使用 | number | 0 |
| tabbar-height 1.24.3+ | 自定义底部标签栏的高度,在拖拽时使用 | number | 0 |
FabSlots 1.24.3+
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义入口按钮内容 | { visible: boolean } |
| list | 自定义扩展按钮内容 | { onItemClick: (item: FabItem, index: number) => void } |
FabEmits
| 事件 | 描述 | 类型 |
|---|---|---|
| click | 点击入口按钮时触发 | (event: any) => void |
| select | 点击扩展按钮时触发 | (item: FabItem, index: number) => void |
| update:offset 1.24.2+ | 因用户拖拽导致位置改变时触发 | (offset: { x: number; y: number }) => void |
FabItem
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| name | 按钮名称 | string | - |
| color | 按钮图标颜色 | string | - |
| background | 按钮背景色 | string | - |
| icon | 按钮图标 | string | - |
| icon-family | 按钮图标族 | string | - |
FabItemProps 1.24.3+
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| root-class | 组件根元素类名 | string | - |
| root-style | 组件根元素样式 | StyleValue | - |
| name | 按钮名称 | string | - |
| color | 按钮图标颜色 | string | - |
| background | 按钮背景色 | string | - |
| icon | 按钮图标 | string | - |
| icon-family | 按钮图标族 | string | - |
FabItemSlots 1.24.3+
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义按钮内容 | - |
FabItemEmits 1.24.3+
| 事件 | 描述 | 类型 |
|---|---|---|
| click | 点击按钮时触发 | (event: any) => void |
主题定制
CSS 变量
scss
page,
.sar-portal {
--sar-fab-z-index: 1000;
--sar-fab-right: 48rpx;
--sar-fab-bottom: 96rpx;
--sar-fab-mask: var(--sar-mask-illegible);
--sar-fab-duration: var(--sar-duration-fast);
--sar-fab-item-gap: 32rpx;
--sar-fab-item-active-opacity: var(--sar-active-opacity);
--sar-fab-item-btn-size: 96rpx;
--sar-fab-item-btn-font-size: 48rpx;
--sar-fab-item-btn-color: var(--sar-white);
--sar-fab-item-btn-bg: var(--sar-primary);
--sar-fab-item-btn-box-shadow: var(--sar-shadow-lg);
--sar-fab-item-name-gap: 16rpx;
--sar-fab-item-name-font-size: var(--sar-text-base);
--sar-fab-item-name-color: var(--sar-white);
}