因業務上的需求,須要在某些點擊區域上增長這樣一層邏輯:若是該用戶沒有受權基本信息 / 手機號,在點擊該區域時,先彈出微信的受權彈窗,受權成功後再進行下一步的業務操做。javascript
其中用到了 @dannnney 的weapp-event傳送門css
本案例 github源碼 歡迎star~~html
由於受權基本信息 / 手機號 必須使用小程序原生的的button,而後指定open-type
後經過回調才能拿到相關信息(wx.getUserInfo()
已經不能彈窗啦,必須經過button彈窗),可是須要前置受權的點擊區域樣式又不必定是button的樣式,因此決定使用一個透明的原生button 覆蓋在點擊區域之上,在視覺上實現無差異受權。經過是否受權字段來決定該按鈕是否顯示。java
由於小程序中可能有多個須要相同受權的點擊區域,因此決定用觀察者模式來實現,即其中一個組件受權後,更新全部相同受權的組件,隱藏受權button。git
由於須要讓受權button徹底覆蓋在點擊區域之上,因此須要讓slot裏面的內容撐開父級定位元素,而後受權button絕對定位在該父元素內,寬高都設爲100%便可。也能夠經過小程序組件的externalClasses
從組件外部指定樣式。代碼以下:github
.wrapper {
position: relative;
width: 100%;
height: 100%;
.auth {
position: absolute;
width: 100%;
height: 100%;
opacity: 0;
top: 0;
left: 0;
z-index: 10;
}
}
複製代碼
<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>
複製代碼
效果:小程序
未設置透明度(青色區域均爲受權按鈕)微信
將透明度設爲0之後app
properties
openType
經過設置不一樣的參數來設置組件的受權類型data
authorized
經過該值控制 受權按鈕是否顯示attached
attached
階段,判斷用戶是否受權,若是受權,直接將authorized
置爲 false
detached
須要在組件外部綁定點擊區域自己的點擊事件,在已經受權的狀況下會觸發點擊回調。ui
<authorization-block bind:action="callBack" m-class="xxx">
<view class="u-m">
xxxxxxx
</view>
</authorization-block>
複製代碼
詳細代碼:
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') {
/* * 獲取到用戶手機號後的業務代碼 * */
vm._triggerEvent(detail)
}
},
getUserInfo ({detail: {userInfo: {avatarUrl, nickName}, errMsg}}) {
const vm = this
if (errMsg === 'getUserInfo:ok') {
/* * 獲取到用戶信息後的業務代碼 * */
vm._triggerEvent()
}
},
_triggerEvent (arg) {
const vm = this
/* * 觸發監聽器後,更新全局變量,觸發點擊區域自己的點擊回調 * */
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
}
/* * 從 狀態管理 或者 globalData 或者別的途徑 判斷用戶是否受權 * */
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)
}
})
複製代碼
open-type
的相關邏輯,案例中只有 userInfo 和phoneNumber。