介绍
粘性布局组件,用于在页面滚动时将元素固定在指定位置。
css 的粘性定位有更好的性能和体验,如果能满足需求,则不需要使用 Sticky 组件。
Sticky 组件通常用于需要粘性定位的元素受父元素范围限制的情景,因为 Sticky 组件能跳脱父元素的范围限制。
INFO
需在模拟器或移动设备上查看效果,因为 uni.createIntersectionObserver 在 pc 端获取的数据是不正确的。
引入
js
import Sticky from 'sard-uniapp/components/sticky/sticky.vue'
import StickyBox from 'sard-uniapp/components/sticky-box/sticky-box.vue'代码演示
吸顶
使用 offset-top 设置粘性定位元素距离视窗顶部的距离。
如果是自定义导航栏,则需要自行加上状态栏和导航栏的高度。
黏住视窗状态时使用的是 fixed 定位。
vue
<template>
<sar-sticky :offset-top="safeAreaTop">
<sar-button inline theme="danger">吸顶</sar-button>
</sar-sticky>
</template>
<script setup lang="ts">
import { safeAreaTop } from '@/utils'
</script>@/utils
ts
import { createBemStruct, getWindowInfo } from 'sard-uniapp'
export const createBem = createBemStruct({
namespace: 'doc',
blockSeparator: '-',
elementSeparator: '__',
modifierSeparator: '_',
})
export const navbarHeight = uni.upx2px(88)
export const statusBarHeight = getWindowInfo().statusBarHeight
export const safeAreaTop = navbarHeight + statusBarHeightjs
import { createBemStruct, getWindowInfo } from "sard-uniapp";
const createBem = createBemStruct({
namespace: "doc",
blockSeparator: "-",
elementSeparator: "__",
modifierSeparator: "_"
});
const navbarHeight = uni.upx2px(88);
const statusBarHeight = getWindowInfo().statusBarHeight;
const safeAreaTop = navbarHeight + statusBarHeight;
export {
createBem,
navbarHeight,
safeAreaTop,
statusBarHeight
};动态插入
即使是动态插入的数据,Sticky 组件也能重新计算其位置。
vue
<template>
<view style="margin-left: 120rpx">
<sar-button inline @click="visible = true">点击生成</sar-button>
<sar-sticky :offset-top="safeAreaTop" style="margin-top: 20rpx">
<sar-button v-if="visible" inline theme="success">动态生成</sar-button>
</sar-sticky>
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { safeAreaTop } from '@/utils'
const visible = ref(false)
</script>vue
<template>
<view style="margin-left: 120rpx">
<sar-button inline @click="visible = true">点击生成</sar-button>
<sar-sticky :offset-top="safeAreaTop" style="margin-top: 20rpx">
<sar-button v-if="visible" inline theme="success">动态生成</sar-button>
</sar-sticky>
</view>
</template>
<script setup lang="js">
import { ref } from "vue";
const visible = ref(false);
</script>吸底
使用 offset-bottom 设置粘性定位元素距离视窗底部的距离。
vue
<template>
<sar-sticky
:offset-bottom="40"
style="margin-top: 900rpx; margin-left: 300rpx"
>
<sar-button inline theme="warning">吸底</sar-button>
</sar-sticky>
</template>吸顶和吸底
可以同时使用 offset-top 和 offset-bottom 设置粘性定位元素距离视窗顶部和底部的距离。
vue
<template>
<sar-sticky
:offset-top="safeAreaTop"
:offset-bottom="40"
style="margin-left: 440rpx"
>
<sar-button inline theme="info">吸顶和吸底</sar-button>
</sar-sticky>
</template>
<script setup lang="ts">
import { safeAreaTop } from '@/utils'
</script>容器中的吸顶
如果要将元素限制在某个范围之内,可以使用 StickyBox 组件包裹着 Sticky 组件。
黏住 StickyBox 组件状态时使用的是 absolute 定位,因此 Sticky 组件不能被其他含有响应其绝对定位于 StickyBox 的定位样式的元素包裹。
vue
<template>
<sar-sticky-box style="height: 400rpx; background: var(--sar-emphasis-bg)">
<sar-sticky :offset-top="offsetTop" style="margin-left: 300rpx">
<sar-button inline background="var(--sar-purple)">
容器中的吸顶
</sar-button>
</sar-sticky>
</sar-sticky-box>
</template>
<script setup lang="ts">
import { safeAreaTop } from '@/utils'
const offsetTop = safeAreaTop + 50
</script>vue
<template>
<sar-sticky-box style="height: 400rpx; background: var(--sar-emphasis-bg)">
<sar-sticky :offset-top="offsetTop" style="margin-left: 300rpx">
<sar-button inline background="var(--sar-purple)">
容器中的吸顶
</sar-button>
</sar-sticky>
</sar-sticky-box>
</template>
<script setup lang="js">
import { safeAreaTop } from "@/utils";
const offsetTop = safeAreaTop + 50;
</script>容器中的吸底
vue
<template>
<sar-sticky-box
style="
display: flex;
align-items: flex-end;
height: 400rpx;
background: var(--sar-emphasis-bg);
"
>
<sar-sticky :offset-bottom="40" style="margin-left: 300rpx">
<sar-button inline background="var(--sar-indigo)">
容器中的吸底
</sar-button>
</sar-sticky>
</sar-sticky-box>
</template>容器中的吸顶和吸底
vue
<template>
<sar-sticky-box
style="
display: flex;
align-items: center;
height: 600rpx;
background: var(--sar-emphasis-bg);
"
>
<sar-sticky
:offset-top="offsetTop"
:offset-bottom="40"
style="margin-left: 300rpx"
>
<sar-button inline background="var(--sar-indigo)">
容器中的吸顶和吸底
</sar-button>
</sar-sticky>
</sar-sticky-box>
</template>
<script setup lang="ts">
import { safeAreaTop } from '@/utils'
const offsetTop = safeAreaTop + 50
</script>vue
<template>
<sar-sticky-box
style="
display: flex;
align-items: center;
height: 600rpx;
background: var(--sar-emphasis-bg);
"
>
<sar-sticky
:offset-top="offsetTop"
:offset-bottom="40"
style="margin-left: 300rpx"
>
<sar-button inline background="var(--sar-indigo)">
容器中的吸顶和吸底
</sar-button>
</sar-sticky>
</sar-sticky-box>
</template>
<script setup lang="js">
import { safeAreaTop } from "@/utils";
const offsetTop = safeAreaTop + 50;
</script>API
StickyProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| root-class | 组件根元素类名 | string | - |
| root-style | 组件根元素样式 | StyleValue | - |
| offset-top | 吸顶距离,单位px | number | - |
| offset-bottom | 吸底距离,单位px | number | - |
| z-index | 粘性元素的层级 | number | - |
StickySlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义默认内容 | - |