微信小程序用户隐私协议弹窗

341 阅读1分钟

直接贴代码吧!样式可以自行修改!

使用方法:

将组建引入所需要隐私弹窗的页面内

触发方式:

uni.$emit('$privacy', () => {
//这里写隐私协议弹窗后需要执行的代码
})

组件代码

  <view v-if="visible" class="wrap"  @touchmove.stop>
    <view class="box">
      <view class="title">
        <image class="logo" src="小程序图片" mode="cover"></image>
        <view>小程序名称</view>
      </view>
      <view class="desc">
        <view>在使用服务之前请仔细阅读</view>
        <view @click="openPrivacy" class="link">{{ privacyContractName || '隐私保护指引' }}</view>
      </view>
      <view class="btns">
        <button class="btn" @click="onCancel">取消</button>
        <button id="agree-btn" class="btn" type="primary" open-type="agreePrivacyAuthorization" @agreeprivacyauthorization="onConfirm">同意</button>
      </view>
    </view>
  </view>
</template>
<script>
export default {
  name: 'PrivacyBox',
  data() {
    return {
      visible: false,
      successFn: null,
      privacyContractName: '',
    };
  },
 
  mounted() {
    uni.$on('$privacy', this.start);
  },
  methods: {
    start(fn) {
      uni.getPrivacySetting({
        success: (res) => {
          console.log(res); // 返回结果为: res = { needAuthorization: true/false, privacyContractName: '《xxx隐私保护指引》' }
          if (res.needAuthorization) {
            this.privacyContractName = res.privacyContractName;
            // 设置同意后事件
            this.successFn = fn;
            // console.log('弹出隐私协议')
            this.showPopup();
          } else {
            this.successFn = null;
            fn && fn();
          }
        },
        fail: () => { },
        complete: () => { },
      });
    },
    showPopup() {
      this.visible = true;
    },
    onCancel() {
      this.visible = false;
      uni.navigateBack({ delta: 1 });
    },
    async onConfirm() {
      this.successFn && this.successFn();
      this.visible = false;
    },
    openPrivacy() {
      uni.openPrivacyContract({
        success: () => { }, // 打开成功
        fail: () => { }, // 打开失败
        complete: () => { },
      });
    },
  },
};
</script>

<style scoped lang="scss">
.wrap {
  position: fixed;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.5);
  z-index: 100000;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  top: 0;
  left: 0;


  &.show {
    opacity: 1;
    transition: all 0.25s;
  }
}

.box {
  background-color: #f8f6f5;
  padding: 20rpx 40rpx 40rpx 40rpx;
  border-radius: 20rpx;
  box-sizing: border-box;
  width: 80%;

  .title {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 20rpx;
    font-size: 24rpx;
    margin-bottom: 32rpx;
    font-weight: 500;

    .logo {
      width: 40rpx;
      height: 40rpx;
      display: block;
      border-radius: 100%;
    }
  }

  .desc {
    line-height: 1;
    margin-bottom: 32rpx;
    line-height: 2rem;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;

    .link {
      color: #3e83e5;
    }
  }

  .btns {
    display: flex;
    gap: 40rpx;

    .btn {
      border: 1px solid #36875e;
      color: #ad937a;
      flex: 1;
      border-radius: 23px;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: #fff;
      height: 40px;

      &[type="primary"] {
        background-color: #36875e;
        color: #fff;
      }
    }
  }
}

button::after {
  border: none;
  display: none;
}
</style>