Due to business requirements, a layer of logic needs to be added to some click areas: If the user does not have basic authorization information/mobile phone number, the wechat authorization popup window will pop up first when clicking this area, and the next business operation will be performed after the authorization is successful.
It uses @Dannnney’s appellate P-event portal
Github source code welcome star~~
Train of thought
Wx.getuserinfo () does not pop, it has to pop through the button window. However, the click area style that requires pre-authorization is not necessarily a button style, so we decided to use a transparent native button to cover the click area and achieve visual undifferentiated authorization. Whether the button is displayed is determined by whether to authorize the field.
Since there may be multiple click areas in the applet that require the same authorization, we decided to implement the observer mode, that is, after one component is authorized, update all components with the same authorization and hide the authorization button.
style
Since the authorization button needs to be completely overlaid on the click area, the contents of the slot need to be stretched over the parent location element, and the authorization button needs to be absolutely positioned inside the parent element, with both width and height set to 100%. You can also specify styles from outside the component via externalClasses of the applets component. The code is as follows:
.wrapper { position: relative; width: 100%; height: 100%; .auth { position: absolute; width: 100%; height: 100%; opacity: 0; top: 0; left: 0; z-index: 10; }}Copy the code
<view class="wrapper m-class">
<view bind:tap="handleTap">
<slot></slot>
</view>
<block wx:if="{{! authorized}}">
<button
class="auth"
open-type="{{openType}}"
bindgetphonenumber="getPhoneNumber"
bindgetuserinfo="getUserInfo">
</button>
</block>
</view>
Copy the code
Effect:
Transparency not set (all cyan areas are authorization buttons)
After setting transparency to 0
logic
properties
openType
You can set the component authorization type by setting different parameters
data
authorized
This value controls whether the authorization button is displayed
attached
- In the component’s
attached
Phase, determine whether the user is authorized, if authorized, directlyauthorized
Set tofalse
- If the user is not authorized, the listener is initialized
- In the component’s
detached
- Removing listeners
Click events that need to be bound outside the component to the click region itself trigger click callbacks if authorized.
<authorization-block bind:action="callBack" m-class="xxx">
<view class="u-m">
xxxxxxx
</view>
</authorization-block>
Copy the code
Detailed code:
import event from '.. /.. /utils/event'
Component({
externalClasses: ['m-class'].properties: {
openType: {
type: String.value: 'getUserInfo'}},data: {
authorized: false
},
methods: {
getPhoneNumber ({detail}) {
const vm = this
if (detail.errMsg === 'getPhoneNumber:ok') {
/* * Obtain the user's mobile phone number after the service code * */
vm._triggerEvent(detail)
}
},
getUserInfo ({detail: {userInfo: {avatarUrl, nickName}, errMsg}}) {
const vm = this
if (errMsg === 'getUserInfo:ok') {
/* * Get user info * */
vm._triggerEvent()
}
},
_triggerEvent (arg) {
const vm = this
/* * After the listener is triggered, the global variable is updated to trigger the click callback for the click region itself
event.triggerEvent([vm.data.config.eventName], true)
getApp().globalData[vm.data.config.eventName] = true
vm.triggerEvent('action', arg)
},
handleTap () {
const vm = this
vm.triggerEvent('action')
}
},
attached () {
const vm = this
let config
switch (vm.data.openType) {
case 'getUserInfo':
config = {
eventName: 'userInfo'
}
break
case 'getPhoneNumber':
config = {
eventName: 'phoneNumber'
}
break
}
/* * Determine whether the user is authorized by status management or globalData or other means
if (getApp().globalData[config.eventName]) {
vm.setData({
authorized: true})}else {
event.addEventListener([config.eventName], vm, (authorized) => {
if (authorized) {
vm.setData({
authorized: true
})
}
})
}
vm.setData({
config
})
},
detached () {
const vm = this
event.removeEventListener([vm.data.config.eventName], vm)
}
})
Copy the code
other
- It can be expanded according to service needs
open-type
In this case, there are only userInfo and phoneNumber. - The slot cannot be directly bound to tap events. The base library version 1.9.7 and below cannot respond to events, so package a layer of views externally
- If you think it is useful, please give a star on Github. Thank you