需求背景
在很多移动端应用中,广告弹窗是常见的变现手段。但频繁弹出、无法关闭、重复打扰的广告往往会适得其反,导致用户流失。
本文将带你用 uni-app 实现一个**"智能不扰民"的广告弹窗组件,支持 24小时只弹一次**、点击跳转 、优雅关闭,可直接复制使用。
效果预览

功能亮点
- 24小时内只弹一次,避免骚扰
- 点击蒙层或关闭按钮均可关闭
- 图片点击支持跳转活动页
- 不依赖第三方库,开箱即用
核心思路拆解
模板
- .ad-mask 作为半透明遮罩层,点击可关闭广告
- .ad-container 包含广告图片和关闭按钮
- .ad-image 显示广告图片,点击可跳转
- .ad-close-btn 提供关闭按钮
样式
- .ad-mask: 遮罩层样式,居中显示内容
- .ad-container: 广告容器尺寸和定位
- .ad-image: 图片自适应显示
- .ad-close-btn: 关闭按钮样式,圆形设计
逻辑部分
- visible 驱动渲染:控制广告显示状态。
- 事件冒泡"双保险":蒙层绑定
@click="closeAd",内部容器加@click.stop阻止冒泡。 - 频次控制:利用
uni.setStorageSync('lastAdTime', Date.now())记录本次弹出时间,下次onLoad时对比24 h间隔,不到时间绝不骚扰。
使用建议
- 广告图建议尺寸:
600x800rpx,体积 < 100KB - 弹窗频率可升级为后端控制,避免前端被篡改
- 可扩展
uni.request动态获取广告图和跳转链接 - 若需支持"不再提示",可新增
uni.setStorageSync('neverShowAd', true)
完整代码
下载地址:https://download.csdn.net/download/cfxiaoding/92191663
html
<template>
<view class="content">
<!-- 其他元素 -->
<!-- 广告弹窗 -->
<view v-if="visible" class="ad-mask" @click="closeAd">
<view class="ad-container" @click.stop>
<image class="ad-image" :src="adImage" mode="aspectFit" @click="onAdClick" />
<view class="ad-close-btn" @click="closeAd">✕</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
visible: false,
adImage: '/static/ad.png',
adLink: '/pages/activity/index'
}
},
onLoad() {
const last = uni.getStorageSync('lastAdTime');
const now = Date.now();
const oneDay = 24 * 60 * 60 * 1000;
if (!last || now - last > oneDay) {
this.showAd()
}
},
methods: {
showAd() {
this.visible = true;
},
closeAd() {
this.visible = false;
uni.setStorageSync('lastAdTime', Date.now());
},
onAdClick() {
uni.navigateTo({ url: this.adLink });
this.closeAd();
}
}
}
</script>
<style>
.ad-mask {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.ad-container {
position: relative;
width: 600rpx;
height: 800rpx;
}
.ad-image {
width: 100%;
height: 100%;
border-radius: 16rpx;
}
.ad-close-btn {
position: absolute;
top: 16rpx;
right: 16rpx;
color: #fff;
font-size: 36rpx;
background: rgba(0, 0, 0, 0.5);
border-radius: 50%;
width: 60rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
}
</style>