Сверните небольшой компонент предавторизации программы

Апплет WeChat

В связи с потребностями бизнеса необходимо добавить такой слой логики в некоторые области щелчка: если у пользователя нет авторизованной базовой информации/номера мобильного телефона, при нажатии на эту область будет всплывать всплывающее окно авторизации WeChat. сначала, а затем переходите к следующему шагу после успешной авторизации.Одноэтапная бизнес-операция.

который использует @dannnneyweapp-событиепортал

Это делоисходный код на гитхабеДобро пожаловать Star ~~.

идеи

Потому что основная информация авторизации/номер мобильного телефона должны использовать родную кнопку апплета, а затем указатьopen-typeПосле этого актуальную информацию можно получить через обратный вызов (wx.getUserInfo()Окно больше не может быть всплывающим, а кнопка должна использоваться для всплывающего окна), но стиль области клика, требующей предварительной авторизации, не обязательно является стилем кнопки, поэтому я решил использовать прозрачный нативная кнопка для покрытия области клика Дифференциальная авторизация. Отображается ли кнопка, определяется полем авторизации.

Поскольку в апплете может быть несколько областей щелчка, требующих одинаковой авторизации, принято решение использовать режим наблюдателя, то есть после авторизации одного из компонентов все компоненты с такой же авторизацией обновляются, а кнопка авторизации скрыт.

стиль

Поскольку кнопка авторизации должна быть полностью закрыта в области щелчка, необходимо позволить содержимому в слоте растянуть родительский элемент позиционирования, а затем кнопка авторизации абсолютно позиционируется внутри родительского элемента, а ширина и высота устанавливаются до 100%. Вы также можете использовать компонент апплетаexternalClassesУкажите стили вне компонента. код показывает, как показано ниже:

  .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>

Эффект:

Прозрачность не установлена ​​(голубые области — это все кнопки авторизации)

img

После установки прозрачности на 0

img

логика

  • properties
    • openTypeУстановите тип авторизации компонента, задав различные параметры
  • data
    • authorizedКонтролируйте, отображается ли кнопка авторизации через это значение
  • attached
    • в компонентеattachedНа этапе определить, авторизован ли пользователь, если авторизован, то напрямуюauthorizedустановлен вfalse
    • Если пользователь не авторизован, инициализируйте прослушиватель
  • detached
    • удалить слушателя

Событие щелчка самой области щелчка должно быть привязано за пределами компонента, и обратный вызов щелчка будет запущен, если он авторизован.

<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.
  • Событие касания не может быть напрямую привязано к слоту, а базовая версия библиотеки — 1.9.7 и ниже — не может реагировать на событие, поэтому слой представления упаковывается извне.
  • Пожалуйста, указывайте источник при перепечатке, и если вы найдете его полезным, перейдите наgithubДайте звезду, спасибо~