天天看点

小程序自定义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
        })
      }
    }
  })
}