ws-wx-privacy.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
<template> <uni-popup id="privacy" ref="privacyPopup" type="center" :mask-click="false"> <view class="ws-privacy-popup"> <view class="ws-privacy-popup__header"> <!--标题--> <view class="ws-picker__title">{{ title }}</view> </view> <view class="ws-privacy-popup__container"> <text>{{ desc }}</text> <text class="ws-privacy-popup__container-protocol" @click="openPrivacyContract"> {{ protocol }} </text> <text>{{ subDesc }}</text> </view> <view class="ws-privacy-popup__footer"> <button id="agree-btn" class="is-agree" open-type="agreePrivacyAuthorization" @agreeprivacyauthorization="handleAgree" > 同意并继续 </button> <button id="disagree-btn" class="is-disagree" @click="handleDisagree">不同意</button> </view> </view> </uni-popup> </template> <script> import { getContext, getComponent } from './util' const privacyResolves = new Set() // onNeedPrivacyAuthorization的reslove let privacyHandler = null // 注册监听 if (uni.onNeedPrivacyAuthorization) { uni.onNeedPrivacyAuthorization(resolve => { if (typeof privacyHandler === 'function') { privacyHandler(resolve) } }) } export default { name: 'WsWxPrivacy', props: { // 标题 title: { type: String, default: '用户隐私保护提示' }, // 描述 desc: { type: String, default: '感谢您使用本应用,您使用本应用的服务之前请仔细阅读并同意' }, // 隐私保护指引名称 protocol: { type: String, default: '《用户隐私保护指引》' }, // 子描述 subDesc: { type: String, default: '。当您点击同意并开始使用产品服务时,即表示你已理解并同意该条款内容,该条款将对您产生法律约束力。如您拒绝,将无法使用相应服务。' } }, emits: ['disagree', 'agree'], mounted() { privacyHandler = resolve => { const context = getContext() const privacyPopup = getComponent(context, '#privacy-popup') if (privacyPopup) { const privacy = getComponent(privacyPopup, '#privacy') if (privacy && privacy.open) { privacy.open() } } privacyResolves.add(resolve) } }, methods: { /** * 打开隐私协议 */ openPrivacyContract() { wx.openPrivacyContract({ success: () => { console.log('openPrivacyContract success') }, fail: res => { console.error('openPrivacyContract fail', res) } }) }, /** * 拒绝隐私协议 */ handleDisagree() { this.$refs.privacyPopup.close() privacyResolves.forEach(resolve => { resolve({ event: 'disagree' }) }) privacyResolves.clear() this.$emit('disagree') }, /** * 同意隐私协议 */ handleAgree() { this.$refs.privacyPopup.close() privacyResolves.forEach(resolve => { resolve({ event: 'agree', buttonId: 'agree-btn' }) }) privacyResolves.clear() this.$emit('agree') } } } </script> <style lang="scss" scoped> .ws-privacy-popup { width: 600rpx; padding: 48rpx; box-sizing: border-box; overflow: hidden; width: 560rpx; background: linear-gradient(180deg, #e5edff 0%, #ffffff 100%); border-radius: 24rpx; &__header { display: flex; align-items: center; justify-content: center; width: 100%; height: 52rpx; font-size: 36rpx; font-family: PingFangSC-Medium, PingFang SC; font-weight: 550; color: #1a1a1a; line-height: 52rpx; margin-bottom: 48rpx; } &__container { width: 100%; box-sizing: border-box; font-size: 28rpx; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #333333; line-height: 48rpx; margin-bottom: 48rpx; &-protocol { font-weight: 550; color: var(--theme-color); } } &__footer { display: flex; flex-direction: column; .is-disagree, .is-agree { width: 100%; height: 88rpx; background: #ffffff; border-radius: 44rpx; font-size: 32rpx; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #666666; } .is-agree { background: $uni-primary; color: #ffffff; margin-bottom: 18rpx; } button { border: none; outline: none; &::after { border: none; } } } } </style> |
util.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
/** * 获取当前页面上下文 * @returns 页面对象 */ export function getContext() { // eslint-disable-next-line no-undef const pages = getCurrentPages() return pages[pages.length - 1] } /** * 获取上下文中指定节点组件 * @param context 选择器的选择范围,可以传入自定义组件的 this 作为上下文 * @param selector 自定义节点选择器 */ export function getComponent(context, selector) { let component = null // #ifdef H5 context.$children.forEach(child => { if (`#${child.$attrs.id}` === selector) { component = child } else if (child.$children && child.$children.length) { if (getComponent(child, selector)) { component = getComponent(child, selector) } } if (component) { return component } }) // #endif // #ifdef MP-WEIXIN component = context.selectComponent && context.selectComponent(selector) && context.selectComponent(selector).$vm // #endif // #ifdef MP-ALIPAY const alipay = context.$children ? context.$children : context.$vm && context.$vm.$children ? context.$vm.$children : [] component = alipay.find(component => { return `#${component.$scope.props.id}` === selector }) // #endif // #ifdef APP-PLUS const app = context.$children ? context.$children : context.$vm && context.$vm.$children ? context.$vm.$children : [] component = app.find(component => { return `#${component.$attrs.id}` === selector }) // #endif return component } |
使用组件
1 |
<ws-wx-privacy id="privacy-popup" /> |