taro3适配微信小程序隐私协议开发指南

2,084 阅读1分钟

思路

在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)
          }
        }
      }
    })
  })
}

其他

// ./config/index.js配置
const config = {
  ...,
  plugins: [
    [
      '@tarojs/plugin-inject',
      {
        // 兼容taro3.4.6不支持隐私协议方法, 升级后可删除
        components: {
          Button: {
            bindagreeprivacyauthorization: ''
          }
        }
      }
    ]
  ],
}