天天看點

小程式自定義button元件擷取使用者資訊(使用者授權登入)

背景

不得不提一句:微信小程式的:擷取使用者資訊的機制改了(早就改了)。或許是不想讓開發者對使用者“随意”造成困擾——畢竟有的使用者上來隻是為了“逛一圈”。于是增加了“隻有觸發button才能彈窗”的功能。

新版-微信授權機制

<button open-type="getUserInfo" bindgetuserinfo="getUserInfo">授權</button>

//js
onLoad(options){
  this.userAuthorized();
},
getUserInfo(event){
  const userInfo=event.detail.userInfo;
  this.setData({
    userInfo:userInfo
  })
},
authorized(){
  wx.getSetting(){
    success:data=>{
      if(data.authSetting["scope.userInfo"]){
        wx.getUserInfo({
          success:data=>{
            this.setData({
              userInfo:data.userInfo
            })
          }
        })
      }
    }
  }
}      

那麼,從老版小程式一路跟進的使用者就該問了:有了open-type為什麼還要有getUserInfo呢?

要知道,open-type隻是為了擷取使用者資訊,這一點上​

​<button>​

​​和原先的​

​<open-type></open-type>​

​沒有什麼差別,但是!其實擷取完使用者資訊,最重要的其實是“ 登入 ”,這一步就涉及到和伺服器的互動了。

登入操作在伺服器端是有一套非常完整的邏輯的,并不像我們所想的那麼簡單,這一點以後再說。

當然,上面的代碼隻是闡述一下新版微信小程式改進的地方,下面的才是重點:

自定義button元件實作使用者授權登入

為什麼要用“元件”? —— 友善複用!

我們在于主檔案夾同級建立img-button檔案夾,作為button元件的地方。

img-button.wxml

<button bind:getuserinfo="onGetUserInfo"
    open-type="{{openType}}" plain="{{true}}" class="container">
    <slot name="img"></slot>
</button>      

這裡的bind後面必須跟userinfo,這是button元件的API。

小程式自定義button元件擷取使用者資訊(使用者授權登入)

img-button.js

Component({
  // “備注項”——啟用“插槽”
  options:{
    multipleSlot:true
  },
  prototies:{
    openType:{
      type:String
    }
  },
  methods:{
    onGetUserInfo(event){
      this.triggerEvent('getUserinfo',event.detail,{})
    }
  }
})      

元件都有一項“必備屬性”——prototies。(就如同vue中的props——接收資料,規範格式)

接收誰的資料? —— 主wxml中傳來的資料!

既然有接收,就有傳出。不然要元件幹嘛。

對!在methods裡面,元件“告訴”調用它的元素——用getUserInfo定義事件,給你傳一個值event.detail

(這個“getUserInfo”将作為首頁面bind的事件——這裡機制其實和vue中的“$emit”->子元件向父元件傳值,是一樣的)

這樣“一來一往”,自定義元件内部和外面調用檔案就能“互相通路”了。

我們在主檔案的json檔案裡添加“對自定義元件檔案的通路”:

main.json

"usingComponents":{
  ...
  "v-button":"../img-button/img-button"
}      
<v-button wx:if="{{!authorized}}" open-type="getUserInfo" class="..."
      bind:getUserinfo="onGetUserInfo">
  <image slot="img" class="..." src="圖檔路徑" />
</v-button>
<view wx:if="{{authorized}}" class="...">
  <image src="{{userInfo.avatarUrl}}" class="..." />
  <text>{{userInfo.nickName}}</text>
</view>      
data:{
  authorized:false,
  userInfo:null
},
onLoad(options){
  this.userAuthorized();
},
onGetUserInfo(event){
  const userInfo=event.detail.userInfo;   //取出元件内部傳出來的值
  if(userInfo){
    this.setData({
      userInfo,
      authorized:true
    })
  }
},
userAuthorized(){
  wx.getSetting({
    success:data=>{
      if(data.authSetting['scope.userInfo']){
        wx.getUserInfo({
          success:data=>{
            this.setData({
              authorized:true,
              userInfo:data.userInfo
            })
          }
        })
      }else{
        wx.showToast({
          title:'抱歉!請檢查微信',
          icon:'none',
          duration:1200
        })
      }
    }
  })
}