需求背景

常见的变现手段。但就是在很多移动端应用中,广告弹窗频繁弹出、无法关闭、重复打扰的广告往往会适得其反,导致用户流失。

本文将带你用 uni-app 实现一个**“智能不扰民”的广告弹窗组件,支持24小时只弹一次**、点击跳转优雅关闭,可直接复制使用。

效果预览

image-20251023154222615

功能亮点

  • 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

<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>