1

注意:我是使用hooks的,其他可以参考封装思路大同小异的
首先写一个PrivacyAgreement.js文件

import { useState, useEffect } from "react";
// Taro 额外添加的 hooks 要从 '@tarojs/taro' 中引入
import { useDidShow, useDidHide,useReady } from '@tarojs/taro'
import { View, Text, Button } from "@tarojs/components";
import { AtFloatLayout, AtButton } from "taro-ui";
import "./index.scss";
let privacyHandler
let privacyResolves = new Set()
let closeOtherPagePopUpHooks = new Set()
if (wx.onNeedPrivacyAuthorization) {
  wx.onNeedPrivacyAuthorization(resolve => {
    console.log('触发 onNeedPrivacyAuthorization')
    if (typeof privacyHandler === 'function') {
      privacyHandler(resolve)
    }
  })
}
const closeOtherPagePopUp = (closePopUp) => {
  closeOtherPagePopUpHooks.forEach(hook => {
    if (closePopUp !== hook) {
      hook()
    }
  })
}
export default ({
  showPrivacyClk
}) => {
  // 显示和隐藏
  const [showPrivacy, setShowPrivacy] = useState(false)
  const [closePopUpCopy, setclosePopUpCopy] = useState(false)
  useEffect(() => {
    const closePopUp = () => {
      disPopUp()
    }
    console.log('closePopUp',closePopUp)
    privacyHandler = resolve => {
      console.log('3456')
      privacyResolves.add(resolve)
      popUp()
      // 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
      closeOtherPagePopUp(closePopUp)
    }
    closeOtherPagePopUpHooks.add(closePopUp)
    setclosePopUpCopy(closePopUp)
  }, [])
 
  const disPopUp = () => {
    if (showPrivacy === true) {
      wx.showTabBar()
      setShowPrivacy(false)
    }
  }
 
  const popUp = () => {
    if (showPrivacy === false) {
      wx.hideTabBar()
      setShowPrivacy(true)
    }
  }
  // 打开隐私协议页面
  const openPrivacyContractClk = () => {
    wx.openPrivacyContract()
  }
  // 用户点击拒绝隐私协议
  const refundPrivacy = () => {
    wx.showTabBar()
    disPopUp()
    privacyResolves.forEach(resolve => {
      console.log('resolve111', resolve);
      resolve({
        event: 'disagree',
      })
    })
 
    privacyResolves.clear()
    closeOtherPagePopUpHooks.delete(closePopUpCopy)
  }
  // 用户点击同意隐私协议
  const handleAgreePrivacyAuthorization = e => {
    // // 显示tabbar
    wx.showTabBar()
    disPopUp()
    // 这里演示了同时调用多个wx隐私接口时要如何处理:让隐私弹窗保持单例,点击一次同意按钮即可让所有pending中的wx隐私接口继续执行 (看page/index/index中的 wx.getClipboardData 和 wx.startCompass)
    privacyResolves.forEach(resolve => {
      console.log('resolve2222', resolve);
      resolve({
        event: 'agree',
        buttonId: 'agree-btn'
      })
    })
    privacyResolves.clear()
  }
  return (
    <View>
      {
        showPrivacy ?
          (
            <View>
              <View className="privacyAgreementMask"></View>
              <View className="privacyAgreementIdx">
                在您使用小程序服务之前,请您仔细阅读<Text onClick={openPrivacyContractClk} className="privacyTitle">《小程序隐私保护协议》</Text>
                。如您同意该隐私保护指引,请点击“同意”开始使用小程序
                <View className="pivacyAgreementBtn">
                  <View className="btnLeftCon"><AtButton type='primary' full={false} onClick={refundPrivacy}>拒绝</AtButton></View>
                  <View className="btnLeftCon btnRightCon">
                    <Button id="agree-btn" class="agree" open-type="agreePrivacyAuthorization" onAgreeprivacyauthorization={handleAgreePrivacyAuthorization}>同意</Button>
                  </View>
                </View>
              </View>
            </View>
          ) : ''
      }
    </View>);
};

样式文件index.scss如下

.privacyAgreementMask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, .4);
  z-index: 998;
}
 
.privacyAgreementIdx {
  position: fixed;
  left: 0;
  bottom: 0;
  background-color: #fff;
  height: 400rpx;
  border-radius: 10rpx;
  box-sizing: border-box;
  padding: 50rpx 32rpx;
  box-shadow: 0px 2px 25px 0px rgba(189, 189, 189, 0.2);
  z-index: 999;
 
  .privacyTitle {
    color: skyblue;
  }
 
  .pivacyAgreementBtn {
    display: flex;
    justify-content: center;
    margin-top: 100rpx;
 
    .btnLeftCon {
      margin-right: 40rpx;
 
      &:last-child {
        margin-right: 0;
      }
 
      .at-button {
        width: 160rpx;
        height: 70rpx;
        line-height: 70rpx;
        font-size: 24rpx;
        color: #57bf6a;
        background-color: #f2f2f2;
      }
 
      button {
        width: 160rpx !important;
        height: 70rpx !important;
        line-height: 70rpx !important;
        font-size: 24rpx !important;
        color: #57bf6a !important;
        background-color: #f2f2f2 !important;
      }
    }
 
    .btnRightCon {
      .at-button {
        color: #fff;
        background-color: #57bf6a;
      }
 
      button {
        color: #fff !important;
        background-color: #57bf6a !important;
      }
    }
  }
}

在需要用到隐私协议的组件或者api的页面里面引用

import { useState, useEffect } from "react";
import Taro from "@tarojs/taro";
import {
  View
} from "@tarojs/components";
// 引入隐私协议组件
import PrivacyAgreement from "@/components/PrivacyAgreement.js";
 
export default () => {
  // 是否当前页面,用来解决引用隐私弹窗组件,切换我的页面问题
  const [isPageIndex, setIsPageIndex] = useState(true);
  
  // 监听当前路由变化
  useEffect(() => {
    // 获取定位
    gotLocation()
    // 用来解决多个页面引用隐私协议组件,来回拒绝切换导致隐私协议不显示问题(没有这个问题可以不用相关代码)
    const unlisten = Taro.onAppRoute(res => {
      if (res.path === 'pages/index/index') {
        setIsPageIndex(true);
      } else {
        setIsPageIndex(false);
      }
    });
    return () => {
      unlisten && unlisten();
    };
  }, []);
  // 获取到当前位置
  const gotLocation = () => {
    wx.getLocation({
      type: "wgs84",
      success(res) {
        
      },
      fail(rs) {
        // 拒绝隐私协议
        if(rs.errno === 104)return
      },
    });
  }
 
  return (
    <View>
      {/* 隐私协议 */}
      {isPageIndex && <PrivacyAgreement></PrivacyAgreement>}
    </View>
  );
};

浪迹天涯小king
15 声望1 粉丝