在需要出现这个通知的页面,都将这个组件引入,然后将时间进行处理,等到剩余xx时间的时候出现这个弹窗,出现几秒后消失,然后间隔xx秒后再次出现
<template>
<view class="result">
<view class="notice flex-align" :class="{'fold':isShow}">
<image class="logo" :src="logo图片" mode="widthFix">
</image>
<view class="info flex-justify">
<view>
<view class="font-size-left-10 font-bold">内容:啊哈哈哈</text>
</view>
<view class="font-size-left-10 font-bold mt-1">
xxxxxxxxxxxxxxxxxxxx
</view>
</view>
<view>
<view class="text font-bold">倒计时</view>
<view class="count-down flex-center mt-1">
<view v-for="(m,index) in minute.toString()" :key="'m'+index">{{m}}</view>
<view>:</view>
<view v-for="(s,index) in second.toString()" :key="'s'+index">{{s}}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
minute: 0,
second: 0,
residue_time:600,
isShow: false,
timer: null,
timeoutTimer: null
}
},
mounted() {
const that = this
uni.addInterceptor('navigateTo', { //监听跳转
invoke(e) {
that.routeChange()
},
})
uni.addInterceptor('redirectTo', { //监听关闭本页面跳转
invoke(e) {
that.routeChange()
}
})
uni.addInterceptor('switchTab', { //监听tabBar跳转
invoke(e) {
that.routeChange()
}
})
uni.addInterceptor('navigateBack', { //监听返回
invoke(e) {
that.routeChange()
}
})
},
methods: {
routeChange() {
// 监听路由发生改变时清除定时器和延时器
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
if (this.timeoutTimer) {
clearTimeout(this.timeoutTimer)
this.timeoutTimer = null
}
},
init() {
this.getTask()
},
getTask() {
// 剩余时间
this.time1=300
// 间隔时间
this.time2=30
if (this.residue_time > 0) {
this.timer = setInterval(() => {
// 时间格式处理
if (this.residue_time > 0) {
this.countDown();
}
// 剩余300秒开始出现
if (this.residue_time <= Number(this.time1) && !this.isShow) {
// 下次展示时间,如果没有下次时间就是当前时间(直接出现)
const nextTime = uni.getStorageSync('next_time') || this
.residue_time
// 切换页面后不立马出现,等下次出现时间到了再出现
if (nextTime >= this.residue_time) {
// 设置下次出现时间 = 当前时间 - 间隔时间
uni.setStorageSync('next_time', Number(this.residue_time) - Number(this.time2))
// 展示4秒后关闭
this.isShow = true
setTimeout(() => {
this.isShow = false
clearInterval(this.timer)
this.timer = null
}, 4000)
// 每隔30秒弹一次
this.timeoutTimer = setTimeout(() => {
this.getTask()
// 在当前页面间隔时间到了直接出现
uni.removeStorageSync('next_time')
}, Number(this.time2) * 1000)
}
}
if (0 >= this.residue_time) {
this.isShow = false
this.routeChange()
uni.removeStorageSync('next_time')
}
}, 1000)
} else {
this.routeChange()
uni.removeStorageSync('next_time')
}
},
countDown() {
const {
i,
s
} = this.secondsFormat(this.residue_time);
this.minute = i;
this.second = s;
this.residue_time--;
},
// 将秒转为天数,小时。分钟,秒数
secondsFormat(seconds){
let [day, hour, minute, second] = [0, 0, 0, 0]
if (seconds > 0) {
day = Math.floor(seconds / (60 * 60 * 24))
hour = Math.floor(seconds / (60 * 60)) - (day * 24)
minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
}
if (day < 10) {
day = '0' + day
}
if (hour < 10) {
hour = '0' + hour
}
if (minute < 10) {
minute = '0' + minute
}
if (second < 10) {
second = '0' + second
}
return {
d: day,
h: hour,
i: minute,
s: second
};
}
}
}
</script>
<style lang="scss" scoped>
.result {
.notice {
width: calc(100% - 60rpx);
position: fixed;
left: 30rpx;
top: -500rpx;
background: rgba(255, 255, 255, 0.8);
border-radius: 42rpx;
padding: 30rpx;
box-sizing: border-box;
z-index: 9999;
.logo {
width: 72rpx;
height: 72rpx;
margin-right: 20rpx;
}
.info {
width: calc(100% - 92rpx);
view {
color: #0A0C0D;
line-height: 1;
}
}
.text {
color: #000;
font-size: 24rpx;
text {
color: #FF0000;
font-size: 36rpx;
}
}
.count-down {
view {
color: #FF0000;
font-size: 34rpx;
}
}
}
.fold {
animation: appear 0.5s linear forwards, disappear 0.5s linear 3s forwards;
// 出现动画
@keyframes appear {
0% {
top: -500rpx;
}
100% {
top: 40rpx;
}
}
// 消失动画
@keyframes disappear {
0% {
top: 40rpx;
}
100% {
top: -500rpx;
}
}
}
}
</style>
间隔xx时间请求接口:
<template>
<view class="result" @click="gotoPage" v-if="hasData">
<view class="notice flex-align" :class="{'fold':isShow}">
<image class="logo" src="/static/logo.png" mode="widthFix">
</image>
<view class="info flex-justify">
<view>
<view class="font-size-10 font-bold">标题</view>
<view class="font-size-10 font-bold mt-1">内容</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isShow: false,
hasData: false,
timer: null,
timeoutTimer: null
}
},
mounted() {
const that = this
uni.addInterceptor('navigateTo', { //监听跳转
invoke(e) {
that.clearTimer()
},
})
uni.addInterceptor('redirectTo', { //监听关闭本页面跳转
invoke(e) {
that.clearTimer()
}
})
uni.addInterceptor('switchTab', { //监听tabBar跳转
invoke(e) {
that.clearTimer()
}
})
uni.addInterceptor('navigateBack', { //监听返回
invoke(e) {
that.clearTimer()
}
})
},
methods: {
clearTimer() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
if (this.timeoutTimer) {
clearTimeout(this.timeoutTimer)
this.timeoutTimer = null
}
},
init() {
if (uni.getStorageSync('token')) {
this.getInfo()
}
},
getInfo() {
// 先清除定时器
this.clearTimer()
this.$api.sendRequest({
url: 'xxx',
data: {},
success: res => {
if (200 === res.code) {
this.hasData = true
// 定时器去检测时间
this.timer = setInterval(() => {
let nowTime = new Date().getTime()
// 下次展示时间,如果没有下次时间就是当前时间(直接出现)
const nextTime = uni.getStorageSync('next_time') || nowTime;
// 切换页面后不立马出现,等下次展示时间到了再出现
if (nextTime <= nowTime) {
// 设置下次出现时间
uni.setStorageSync('next_time', Number(nowTime) +
Number(res.data.popup_tips_time) * 1000)
// 展示4秒后关闭
this.isShow = true
setTimeout(() => {
this.isShow = false
}, 4000)
// 每隔多少秒弹一次
this.timeoutTimer = setTimeout(() => {
this.getInfo()
// 在当前页面间隔时间到了直接出现
uni.removeStorageSync('next_time')
}, Number(res.data.popup_tips_time) * 1000)
}
}, 1000)
} else {
this.hasData = false
uni.removeStorageSync('next_time')
this.clearTimer()
}
}
});
},
gotoPage() {
// 点击跳转相关页面
}
}
}
</script>
<style lang="scss" scoped>
.result {
.notice {
width: calc(100% - 60rpx);
position: fixed;
left: 30rpx;
top: -500rpx;
background: rgba(255, 255, 255, 0.8);
border-radius: 42rpx;
padding: 30rpx;
box-sizing: border-box;
z-index: 9999;
.logo {
width: 72rpx;
height: 72rpx;
margin-right: 20rpx;
}
.info {
width: calc(100% - 92rpx);
view {
color: #0A0C0D;
line-height: 1;
}
}
.text {
color: #000;
font-size: 24rpx;
text {
color: #FF0000;
font-size: 36rpx;
}
}
.count-down {
view {
color: #FF0000;
font-size: 34rpx;
}
}
}
.fold {
animation: appear 0.5s linear forwards, disappear 0.5s linear 3s forwards;
@keyframes appear {
0% {
top: -500rpx;
}
100% {
top: 40rpx;
// #ifdef APP-PLUS
top: 100rpx;
// #endif
}
}
@keyframes disappear {
0% {
top: 40rpx;
// #ifdef APP-PLUS
top: 100rpx;
// #endif
}
100% {
top: -500rpx;
}
}
}
}
</style>