介绍
给横向滚动容器添加模拟滚动条,一般用于同时展示多个商品、分类列表的场景。
引入
js
import ScrollList from 'sard-uniapp/components/scroll-list/scroll-list.vue'代码演示
基础使用
在默认插槽里编写任意内容。
vue
<template>
<sar-scroll-list>
<view class="flex flex-col gap-20">
<view v-for="(row, i) in rows" :key="i" class="flex gap-32">
<view
v-for="(item, j) in row"
:key="j"
class="flex flex-col justify-center items-center w-120 flex-none"
>
<sar-icon :name="item.icon" size="48rpx" />
<view class="mt-10 text-sm stext-secondary">{{ item.text }}</view>
</view>
</view>
</view>
</sar-scroll-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const rows = ref(
Array(16)
.fill(0)
.reduce(
(rows, _, i) => {
rows[i % 2].push({
text: '文字' + (i + 1),
icon: 'image',
})
return rows
},
[[], []],
),
)
</script>vue
<template>
<sar-scroll-list>
<view class="flex flex-col gap-20">
<view v-for="(row, i) in rows" :key="i" class="flex gap-32">
<view
v-for="(item, j) in row"
:key="j"
class="flex flex-col justify-center items-center w-120 flex-none"
>
<sar-icon :name="item.icon" size="48rpx" />
<view class="mt-10 text-sm stext-secondary">{{ item.text }}</view>
</view>
</view>
</view>
</sar-scroll-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const rows = ref(
Array(16).fill(0).reduce(
(rows2, _, i) => {
rows2[i % 2].push({
text: "\u6587\u5B57" + (i + 1),
icon: "image"
});
return rows2;
},
[[], []]
)
);
</script>滚动条颜色
使用 scrollbar-bg 属性设置滚动条背景色,使用 thumb-bg 属性设置滑块背景色。
也可以通过 css 变量设置。
vue
<template>
<sar-scroll-list
scrollbar-bg="rgba(var(--sar-danger-rgb), 0.2)"
thumb-bg="var(--sar-danger)"
>
<view class="flex flex-col gap-20">
<view v-for="(row, i) in rows" :key="i" class="flex gap-32">
<view
v-for="(item, j) in row"
:key="j"
class="flex flex-col justify-center items-center w-120 flex-none"
>
<sar-icon :name="item.icon" size="48rpx" />
<view class="mt-10 text-sm stext-secondary">{{ item.text }}</view>
</view>
</view>
</view>
</sar-scroll-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const rows = ref(
Array(16)
.fill(0)
.reduce(
(rows, _, i) => {
rows[i % 2].push({
text: '文字' + (i + 1),
icon: 'image',
})
return rows
},
[[], []],
),
)
</script>vue
<template>
<sar-scroll-list
scrollbar-bg="rgba(var(--sar-danger-rgb), 0.2)"
thumb-bg="var(--sar-danger)"
>
<view class="flex flex-col gap-20">
<view v-for="(row, i) in rows" :key="i" class="flex gap-32">
<view
v-for="(item, j) in row"
:key="j"
class="flex flex-col justify-center items-center w-120 flex-none"
>
<sar-icon :name="item.icon" size="48rpx" />
<view class="mt-10 text-sm stext-secondary">{{ item.text }}</view>
</view>
</view>
</view>
</sar-scroll-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const rows = ref(
Array(16).fill(0).reduce(
(rows2, _, i) => {
rows2[i % 2].push({
text: "\u6587\u5B57" + (i + 1),
icon: "image"
});
return rows2;
},
[[], []]
)
);
</script>异步获取数据
组件内部能够通过观察滚动内容宽度变化,动态调整滑块的宽度。
vue
<template>
<sar-skeleton-block v-if="loading" height="252rpx" animated />
<sar-scroll-list v-if="!loading">
<view class="flex flex-col gap-20">
<view v-for="(row, i) in rows" :key="i" class="flex gap-32">
<view
v-for="(item, j) in row"
:key="j"
class="flex flex-col justify-center items-center w-120 flex-none"
>
<sar-icon :name="item.icon" size="48rpx" />
<view class="mt-10 text-sm stext-secondary">{{ item.text }}</view>
</view>
</view>
</view>
</sar-scroll-list>
</template>
<script setup lang="ts">
import { sleep } from 'sard-uniapp'
import { onMounted, ref } from 'vue'
const loading = ref(false)
const rows = ref<any[]>([])
const getData = async () => {
await sleep(1000)
return Array(16)
.fill(0)
.reduce(
(rows, _, i) => {
rows[i % 2].push({
text: '文字' + (i + 1),
icon: 'image',
})
return rows
},
[[], []],
)
}
onMounted(async () => {
loading.value = true
rows.value = await getData()
loading.value = false
})
</script>vue
<template>
<sar-skeleton-block v-if="loading" height="252rpx" animated />
<sar-scroll-list v-if="!loading">
<view class="flex flex-col gap-20">
<view v-for="(row, i) in rows" :key="i" class="flex gap-32">
<view
v-for="(item, j) in row"
:key="j"
class="flex flex-col justify-center items-center w-120 flex-none"
>
<sar-icon :name="item.icon" size="48rpx" />
<view class="mt-10 text-sm stext-secondary">{{ item.text }}</view>
</view>
</view>
</view>
</sar-scroll-list>
</template>
<script setup lang="js">
import { sleep } from "sard-uniapp";
import { onMounted, ref } from "vue";
const loading = ref(false);
const rows = ref([]);
const getData = async () => {
await sleep(1e3);
return Array(16).fill(0).reduce(
(rows2, _, i) => {
rows2[i % 2].push({
text: "\u6587\u5B57" + (i + 1),
icon: "image"
});
return rows2;
},
[[], []]
);
};
onMounted(async () => {
loading.value = true;
rows.value = await getData();
loading.value = false;
});
</script>隐藏滚动条
如果滚动内容宽度小于滚动容器的宽度,会自动隐藏滚动条。
vue
<template>
<sar-scroll-list>
<view class="flex flex-col gap-20">
<view v-for="(row, i) in rows" :key="i" class="flex gap-32">
<view
v-for="(item, j) in row"
:key="j"
class="flex flex-col justify-center items-center w-120 flex-none"
>
<sar-icon :name="item.icon" size="48rpx" />
<view class="mt-10 text-sm stext-secondary">{{ item.text }}</view>
</view>
</view>
</view>
</sar-scroll-list>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const rows = ref(
Array(8)
.fill(0)
.reduce(
(rows, _, i) => {
rows[i % 2].push({
text: '文字' + (i + 1),
icon: 'image',
})
return rows
},
[[], []],
),
)
</script>vue
<template>
<sar-scroll-list>
<view class="flex flex-col gap-20">
<view v-for="(row, i) in rows" :key="i" class="flex gap-32">
<view
v-for="(item, j) in row"
:key="j"
class="flex flex-col justify-center items-center w-120 flex-none"
>
<sar-icon :name="item.icon" size="48rpx" />
<view class="mt-10 text-sm stext-secondary">{{ item.text }}</view>
</view>
</view>
</view>
</sar-scroll-list>
</template>
<script setup lang="js">
import { ref } from "vue";
const rows = ref(
Array(8).fill(0).reduce(
(rows2, _, i) => {
rows2[i % 2].push({
text: "\u6587\u5B57" + (i + 1),
icon: "image"
});
return rows2;
},
[[], []]
)
);
</script>API
ScrollListProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| root-class | 组件根元素类名 | string | - |
| root-style | 组件根元素样式 | StyleValue | - |
| scrollbar-width | 滚动条宽度 | string | - |
| scrollbar-bg | 滚动条的背景色 | string | - |
| thumb-bg | 滑块的的背景色 | string | - |
| upper-threshold | 距左边多远时(单位px),触发 scrolltoupper 事件 | number | 50 |
| lower-threshold | 距右边多远时(单位px),触发 scrolltolower 事件 | number | 50 |
ScrollListSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 自定义默认内容 | - |
ScrollListEmits
| 事件 | 描述 | 类型 |
|---|---|---|
| scroll | 滚动时触发 | ( event: any) => void |
| scrolltoupper | 滚动到左边时触发 | ( event: any) => void |
| scrolltolower | 滚动到右边时触发 | ( event: any) => void |
主题定制
CSS 变量
scss
page,
.sar-portal {
--sar-scroll-list-scrollbar-width: 100rpx;
--sar-scroll-list-scrollbar-height: 8rpx;
--sar-scroll-list-scrollbar-margin-top: 32rpx;
--sar-scroll-list-scrollbar-bg: var(--sar-tertiary-bg);
--sar-scroll-list-scrollbar-thumb-width: 40rpx;
--sar-scroll-list-scrollbar-thumb-bg: var(--sar-primary);
}