uni-app 滚动通知组件的实现
一、实现思路
二、使用scroll-view
组件实现
<template>
<view class="notice">
<scroll-view
class="notice-scroll"
:scroll-y="true"
:scroll-with-animation="true"
:scroll-top="scrollTop"
>
<view :animation="animationData" class="notice-content">
<view
class="notice-item"
v-for="(item, index) in noticeList"
:key="index"
@tap="handleClickNotice(item)"
>
<text>{{ item.text }}</text>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
export default {
name: "notice-bar",
data() {
return {
noticeList: [], // 通知列表
timer: null, // 定时器
interval: 2000, // 滚动时间间隔
scrollTop: 0, // 滚动距离
currentIndex: 0, // 当前通知索引
};
},
props: {
notices: {
// 外部传入的通知列表
type: Array,
default: [],
},
},
mounted() {
this.initNoticeList();
},
methods: {
// 初始化通知列表
initNoticeList() {
const _this = this;
_this.noticeList = _this.notices;
if (_this.noticeList.length > 1) {
_this.timer = setInterval(() => {
_this.handleScrollNotice();
}, _this.interval);
}
},
// 点击通知时触发
handleClickNotice(item) {
this.$emit("click", item);
},
// 滚动通知
handleScrollNotice() {
const len = this.noticeList.length;
if (this.currentIndex === len - 1) {
this.currentIndex = 0;
} else {
this.currentIndex++;
}
this.animateScroll();
},
// 动画滚动
animateScroll() {
const _this = this;
const noticeHeight = 30; // 通知高度,根据实际情况调整
const scrollTop = _this.currentIndex * noticeHeight;
_this.scrollTop = scrollTop;
},
},
destroyed() {
if (this.timer) {
clearInterval(this.timer);
}
},
};
</script>
<style scoped>
.notice {
/* 组件高度,根据实际情况调整 */
height: 60rpx;
overflow: hidden;
}
.notice-scroll {
width: 100%;
height: 100%;
}
.notice-content {
display: flex;
flex-direction: column;
}
.notice-item {
/* 通知高度,根据实际情况调整 */
height: 60rpx;
/* 通知行高,根据实际情况调整 */
line-height: 60rpx;
padding-left: 20rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
这个组件实现了一个纵向滚动的通知列表,可以根据传入的通知列表自动滚动显示。组件初始化时会根据通知列表长度判断是否需要滚动,并设置定时器自动滚动。当用户点击某个通知时,会触发组件的 click 事件,并将点击的通知对象作为参数传递给父组件。组件的动画效果使用了 uni-app 的动画系统,通过创建一个动画对象并设置 translateY 属性来实现纵向滚动效果。
三、使用uni.createAnimation
API 实现
<template>
<view class="notice">
<view :animation="animationData" class="notice-content">
<view
class="notice-item"
v-for="(item, index) in noticeList"
:key="index"
@tap="handleClickNotice(item)"
>
<text>{{ item.text }}</text>
</view>
</view>
</view>
</template>
<script>
export default {
name: "notice-bar",
data() {
return {
noticeList: [], // 通知列表
animation: null, // 动画对象
animationData: {},
timer: null, // 定时器
interval: 2000, // 滚动时间间隔
scrollTop: 0, // 滚动距离
currentIndex: 0, // 当前通知索引
};
},
props: {
notices: {
// 外部传入的通知列表
type: Array,
default: [],
},
},
mounted() {
this.initNoticeList();
const _this = this;
_this.animation = uni.createAnimation({
duration: 500,
timingFunction: "ease-out",
});
},
methods: {
// 初始化通知列表
initNoticeList() {
const _this = this;
_this.noticeList = _this.notices;
if (_this.noticeList.length > 1) {
_this.timer = setInterval(() => {
_this.handleScrollNotice();
}, _this.interval);
}
},
// 点击通知时触发
handleClickNotice(item) {
this.$emit("click", item);
},
// 滚动通知
handleScrollNotice() {
const len = this.noticeList.length;
if (this.currentIndex === len - 1) {
this.currentIndex = 0;
} else {
this.currentIndex++;
}
this.animateScroll();
},
// 动画滚动
animateScroll() {
const _this = this;
const noticeHeight = 30; // 通知高度,根据实际情况调整
const scrollTop = _this.currentIndex * noticeHeight;
if (scrollTop === 0) {
_this.animation.translateY(-scrollTop).step({
duration: 0,
});
} else {
_this.animation.translateY(-scrollTop).step();
}
_this.animationData = _this.animation.export();
},
},
destroyed() {
if (this.timer) {
clearInterval(this.timer);
}
if (this.animation) {
this.animation = null;
}
},
};
</script>
<style scoped>
.notice {
/* 组件高度,根据实际情况调整 */
height: 60rpx;
overflow: hidden;
}
.notice-scroll {
width: 100%;
height: 100%;
}
.notice-content {
display: flex;
flex-direction: column;
}
.notice-item {
/* 通知高度,根据实际情况调整 */
height: 60rpx;
/* 通知行高,根据实际情况调整 */
line-height: 60rpx;
padding-left: 20rpx;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
标签:notice,const,通知,app,滚动,currentIndex,scrollTop,组件,uni
From: https://www.cnblogs.com/yuzhihui/p/17293064.html