思路
在app的onLaunch调用Taro.onNeedPrivacyAuthorization监听什么时候需要去阅读隐私协议, 然后通过ReactDOM.render方法将隐私协议组件插入到页面根元素中. 用户同意或者拒绝后通过ReactDOM.unmountComponentAtNode方法移除隐私协议组件
具体实现
// ./components/Privacy.tsx
// 将该组件直接在app.tsx导入即可
import React from 'react'
import Taro from '@tarojs/taro'
import ReactDom from 'react-dom'
import { View, Button } from '@tarojs/components'
import addLifecycleHook from '@utils/addLifecycleHook'
const resolveSet = new Set<(e: { event: string, buttonId: string }) => void>()
const onCloseSet = new Set<() => void>()
const nonMandatoryPages = new Set(['pages/webview'])
type PrivacyProps = {
onDisagree: () => any
onAgree: () => any
}
// 隐私协议组件Demo
const Privacy: React.FC<PrivacyProps> = ({ onAgree, onDisagree }) => {
return (
<View style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, zIndex: 9999, background: 'rgba(0, 0, 0, .3' }}>
<View>我是隐私协议的内容</View>
<Button onClick={onDisagree}>
拒绝
</Button>
<Button
id='agree'
// @ts-ignore
openType='agreePrivacyAuthorization'
onAgreePrivacyAuthorization={onAgree}
>
同意
</Button>
</View>
)
}
export const popUpPrivacy = (rootId) => {
const portalId = `PrivacyId_${rootId}`
const root = document.getElementById(rootId)
let portal = document.getElementById(portalId)
if (!portal) {
portal = document.createElement('view')
portal.id = portalId
}
if (root && portal) {
root.appendChild(portal)
const onClose = () => ReactDom.unmountComponentAtNode(portal!)
const onAgree = () => {
onCloseSet.forEach(close => close())
resolveSet.forEach(resolve => {
resolve({
event: 'agree',
buttonId: 'agree'
})
})
}
onCloseSet.add(onClose)
ReactDom.render(
<Privacy
onAgree={onAgree}
onDisagree={Taro.exitMiniProgram}
/>
, portal)
}
}
if (process.env.TARO_ENV === 'weapp') {
addLifecycleHook('appHooks', 'onLaunch', () => {
Taro.onNeedPrivacyAuthorization?.(resolve => {
resolveSet.add(resolve)
})
})
addLifecycleHook('pageHooks', 'onReady', () => {
Taro.getPrivacySetting?.({
success: (e) => {
const pages = Taro.getCurrentPages()
const currentPage = pages[pages.length - 1]
if (e.needAuthorization && !nonMandatoryPages.has(currentPage.route)) {
try {
popUpPrivacy(currentPage.$taroPath)
} catch (err) {
console.error(err)
}
}
}
})
})
}
其他
- 低版本Taro3可使用@tarojs/plugin-inject去支持Button的onAgreePrivacyAuthorization事件
// ./config/index.js配置
const config = {
...,
plugins: [
[
'@tarojs/plugin-inject',
{
// 兼容taro3.4.6不支持隐私协议方法, 升级后可删除
components: {
Button: {
bindagreeprivacyauthorization: ''
}
}
}
]
],
}