因(yin)業(ye)務上(shang)的需求,需要在某些(xie)點(dian)擊區域(yu)(yu)上(shang)增加這樣一層邏輯(ji):如果該(gai)用戶(hu)沒(mei)有授權基本信息(xi) / 手機號,在點(dian)擊該(gai)區域(yu)(yu)時,先彈(dan)(dan)出微(wei)信的授權彈(dan)(dan)窗,授權成功后再(zai)進(jin)行下一步的業(ye)務操(cao)作。
其中用到了 @ dannnney 的weapp-event 傳送(song)門
本案例 github源碼 歡迎(ying)star~~
因為授(shou)權(quan)基本(ben)信息(xi) / 手(shou)機號 必(bi)須使(shi)用(yong)小程序原生的(de)的(de)button,然(ran)后指定(ding) open-type 后通過(guo)回(hui)調才能拿到相關(guan)信息(xi)( wx.getUserInfo() 已經不能彈窗(chuang)啦,必(bi)須通過(guo)button彈窗(chuang)),但是(shi)需要(yao)前置授(shou)權(quan)的(de)點擊區域(yu)樣式又不一定(ding)是(shi)button的(de)樣式,所以(yi)決(jue)定(ding)使(shi)用(yong)一個透(tou)明的(de)原生button 覆蓋在點擊區域(yu)之(zhi)上,在視覺上實現無差別授(shou)權(quan)。通過(guo)是(shi)否(fou)授(shou)權(quan)字段(duan)來決(jue)定(ding)該(gai)按鈕(niu)是(shi)否(fou)顯(xian)示。
因為小(xiao)程序中(zhong)可能有(you)(you)多個需(xu)要相同(tong)授(shou)(shou)權(quan)的(de)點擊區(qu)域(yu),所(suo)以(yi)決(jue)定用(yong)觀察者模(mo)式來實現(xian),即其中(zhong)一(yi)個組(zu)(zu)件授(shou)(shou)權(quan)后(hou),更新(xin)所(suo)有(you)(you)相同(tong)授(shou)(shou)權(quan)的(de)組(zu)(zu)件,隱藏授(shou)(shou)權(quan)button。
因為需(xu)要(yao)(yao)讓(rang)授(shou)權button完全覆蓋(gai)在點(dian)擊(ji)區(qu)域之上,所(suo)以(yi)(yi)需(xu)要(yao)(yao)讓(rang)slot里(li)面的(de)內(nei)容撐開(kai)父(fu)(fu)級定位元(yuan)素(su),然后授(shou)權button絕(jue)對定位在該父(fu)(fu)元(yuan)素(su)內(nei),寬高都設(she)為100%即可。也可以(yi)(yi)通(tong)過小程序組件(jian)的(de) externalClasses 從組件(jian)外部(bu)指定樣式。代碼如下:
.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>
復制代碼
效果:
未設置透(tou)明度(du)(青色區域均為(wei)授(shou)權按鈕)

將透明度設為0以后

需(xu)要在組件外(wai)部(bu)綁(bang)定(ding)點擊區域本身的(de)點擊事件,在已經授(shou)權(quan)的(de)情況下會觸發點擊回調。
<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)
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
}
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)
}
})
復制代碼