infinite-scroll 无限循环滚动
index.wxml
<view class="infinite-scroll custom-class" style="{{style}}">
<view class="infinite-scroll__item item-class" wx:for="{{column}}">
<slot wx:if="{{useSlot}}" name="item{{index}}"></slot>
<text wx:else>{{item.content}}</text>
</view>
</view>
index.ts
import { type IOptions } from './type'
Component({
externalClasses: ['custom-class', 'item-class'],
options: {
multipleSlots: true,
},
properties: {
useSlot: Boolean,
options: {
type: Object,
value: {
list: [],
direction: '',
num: 0,
itemHeight: 0,
itemWidth: 0,
animationDuration: 10,
},
observer: 'init',
},
},
data: {
column: [] as any[],
style: '',
},
methods: {
init() {
let {
list,
direction,
num = 0,
itemHeight = 0,
itemWidth = 0,
animationDuration,
} = this.data.options as IOptions
direction = direction ?? 'column'
const repeat = list.slice(0, num)
const column = [...list, ...repeat]
setTimeout(() => {
this.triggerEvent('column', column)
})
const styleEnum = {
column: `height: ${
num * itemHeight
}rpx;--translate: translateY(-${
list.length
}00%);--direction: ${direction};--animation-duration: ${animationDuration}s`,
row: `width: ${num * itemWidth}rpx;--translate: translateX(-${
list.length
}00%);--direction: ${direction};--itemWidth: ${itemWidth}rpx;--animation-duration: ${animationDuration}s`,
}
this.setData({
style: styleEnum[direction],
column,
})
},
},
})
type.ts
export interface IOptions {
list: Array<{ content: string }>
direction: TDirection
animationDuration: number
num?: number
itemHeight?: number
itemWidth?: number
}
type TDirection = 'column' | 'row'
index.scss
.infinite-scroll {
position: relative;
display: flex;
flex-direction: var(--direction);
overflow: hidden;
&__item {
width: var(--itemWidth, 100%);
animation: scroll 10s linear infinite;
animation-duration: var(--animation-duration);
display: flex;
align-items: center;
flex-shrink: 0;
justify-content: center;
}
}
@keyframes scroll {
0% {
transform: translate(0, 0, 0);
}
100% {
transform: var(--translate);
}
}
使用
<infinite-scroll
options="{{options}}"
item-class="infinite-scroll-item"
bind:column="getScrollColumn"
useSlot>
<block wx:for="{{column}}">
<view slot="item{{index}}">
<image
src="{{item.avatar}}"
class="infinite-scroll-item__avator"></image>
<text>{{item.content}}</text>
</view>
</block>
</infinite-scroll>
import {IOptions} from 'infinite-scroll/type'
const options:IOptions = {
list: [{ content: '1', avatar: '1' }],
direction: 'column',
num: 2,
itemHeight: 44,
itemWidth: 750,
animationDuration: 10,
}
getScrollColumn(e) {
this.setData({
column: e.detail,
})
},
.infinite-scroll-item {
justify-content: flex-start !important;
&__avator {
width: 36rpx;
height: 36rpx;
}
}
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|
| useSlot | 是否使用自定义内容插槽 | string | |
| options | 选项 | object | |
options
| 参数 | 说明 | 类型 | 默认值 |
|---|
| list | 原始数据 | array | |
| direction | 滚动方向 | string | column/row |
| num | 显示条数 | number | |
| itemHeight | direction:column 时的单行高度 | number | |
| itemWidth | direction:row 时的单行宽度 | number | |
| animationDuration | 动画时长 | number | |
外部样式类
| 类名 | 说明 |
|---|
| custom-class | 根节点样式类 |
| item-class | 项节点样式类 |