#yyds干货盘点#【愚公系列】2022年12月 微信小程序-小程序登录面板功能实现

时间:2022-12-31 14:11:01

前言

一、小程序登录面板功能实现

1.主页面

<button bindtap="showLoginPanel" type="primary">手动打开登录面板</button>
<LoginPanel show="{{showLoginPanel}}"></LoginPanel>
showLoginPanel(e) {
  this.setData({
    showLoginPanel2: true
  })
},

2.登录组件

// LoginPanel 
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    show: {
      type: Boolean,
      value: false
    }
  },

  observers: {
    'show': function (value) {
      this.setData({
        visible: value
      })
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    visible: false
  },

  /**
   * 组件的方法列表
   */
  methods: {
    close(e){
      this.setData({
        visible: false
      })
    },
    async login(e){
      let {
        userInfo,
        encryptedData,
        iv
      } = e.detail

      let token = null
      let tokenIsValid = false
      try {
        await getApp().wxp.checkSession()
        token = wx.getStorageSync('token')
        if (token) {
          tokenIsValid = true
        }
      } catch (error) {}

      if (!tokenIsValid) {
        let res1 = await getApp().wxp.login()
        let code = res1.code
        let res = await getApp().wxp.request({
          url: 'http://localhost:3000/user/wexin-login2',
          method: 'POST',
          header: {
            'content-type': 'application/json'
          },
          data: {
            code,
            userInfo,
            encryptedData,
            iv
          }
        })
        console.log('登录接口请求成功', res.data)
        token = res.data.data.authorizationToken
        wx.setStorageSync('token', token)
        console.log('authorization', token)
      }

      getApp().globalData.token = token
      wx.showToast({
        title: '登陆成功了',
      })
      this.close()
      //this.triggerEvent('loginSuccess')
      getApp().globalEvent.emit('loginSuccess')
    },
  }
})
{
  "component": true,
  "usingComponents": {
    "pop-up":"../pop-up2"
  }
}
<pop-up visible="{{visible}}">
	<view slot="content">
		<view class="picker-view">
			<view class="picker-view__pane">
				<text bindtap="close">取消</text>
			</view>
			<text>引导用户单击按钮登录:</text>
			<button bindgetuserinfo="login" open-type="getUserInfo" type="primary">登陆</button>
		</view>
	</view>
</pop-up>
/* components/login2/index.wxss */

.picker-view {
  width: 100%;
  display: flex;
  background-color: #fff;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  bottom: 0rpx;
  left: 0rpx;
}

.picker-item {
  line-height: 70rpx;
  margin-left: 5rpx;
  margin-right: 5rpx;
  text-align: center;
}

.picker-view__pane {
  height: 100rpx;
  width: 100%;
  padding: 20rpx 32rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-sizing: border-box;
}

.picker-view__pane text{
  color: #00cc88;
  font-size: 30rpx;
}

.pick-view__group {
  width: 96%;
  height: 450rpx;
}

3.发布订阅组件

class Event{
  cache 
  constructor(){
    this.cache = {}
  }
  // 监听
  on(eventType, func){
    // this.cache[eventType] = func
    (this.cache[eventType] || (this.cache[eventType] = [])).push(func)
  }
  // 移除监听
  off(eventType, func){
    if (func){
      let stack = this.cache[eventType]
      if (stack && stack.length > 0){
        for(let j=0;j<stack.length;j++){
          if (stack[j] == func){
            stack.splice(j, 1)
            break
          } 
        }
      }
    }else{
      delete this.cache[eventType]
    }
  }
  // 监听一次
  once(eventType, func){
    function on(){
      this.off(eventType, on)
      func.apply(this, arguments)
    }
    this.on(eventType, on)
  }
  // 发布订阅通知
  emit(eventType, ...args){
    const stack = this.cache[eventType]
    if (stack && stack.length > 0){
      stack.forEach(item => item.apply(this, args))
    }
  }
}

export default Event

4.pop-up面板组件

Component({
  options: {
    multipleSlots: true // 在组件定义时的选项中启用多slot支持
  },
  /**
   * 组件的属性列表
   */
  properties: {
    visible: {
      type: Boolean,
      value: false
    }
  },

  /**
   * 组件的初始数据
   */
  data: {},

  ready(){
    this.triggerEvent('ready')
  },

  /**
   * 组件的方法列表
   */
  methods: {
    popPreventTouchmove() { },
    popPreventTouchmove2() { },
    popPreventTouchmove3() { },
    cityChange() { },
    close() {
      this.triggerEvent('close')
    },
    handleClickMask(e) {
      // console.log(e)
      if (e.target.dataset.type !== 'unclose') this.close()
    }
  }
})
<view catchtouchmove="popPreventTouchmove">
  <view class="q-pp-mask  {{ visible ? 'q-pp-mask-show' : '' }} ptp_exposure" bindtap="handleClickMask" catchtouchmove="popPreventTouchmove">
    <view class=" q-pp {{ visible ? 'q-pp-show' : '' }}" catchtouchmove="popPreventTouchmove">
      <slot name="content" ></slot>
    </view>
  </view>
</view>
.q-pp {
  position: fixed;
  width: 100%;
  box-sizing: border-box;
  left: 0;
  right: 0;
  bottom: 0;
  background: #f7f7f7;
  transform: translate3d(0, 100%, 0);
  transform-origin: center;
  transition: all 0.2s ease-in-out;
  z-index: 900;
  visibility: hidden;
}

.q-pp-show {
  transform: translate3d(0, 0, 0);
  visibility: visible;
}

.q-pp-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.7);
  z-index: 900;
  transition: all 0.2s ease-in-out;
  opacity: 0;
  visibility: hidden;
}

.q-pp-mask-show {
  opacity: 1;
  visibility: visible;
}

5.wxp

import {
  promisifyAll
} from 'miniprogram-api-promise';

const wxp = {}
promisifyAll(wx, wxp)

//鉴权
wxp.request2 = function (args) {
  let token = wx.getStorageSync('token')
  if (token) {
    if (!args.header) args.header = {}
    args.header['Authorization'] = `Bearer ${token}`
  }
  return wxp.request(args).catch(function (reason) {
    console.log('reason', reason)
  })
}

// 登录
wxp.request3 = function(args){
  let token = wx.getStorageSync('token')
  if (!token){
    return new Promise((resolve, reject)=>{
      let pageStack = getCurrentPages()
      if (pageStack && pageStack.length > 0) {
        let currentPage = pageStack[pageStack.length-1]
        currentPage.setData({
          showLoginPanel2:true
        })
        getApp().globalEvent.once("loginSuccess", ()=>{
          wxp.request2(args).then(res=>{
            resolve(res)
          }, err=>{
            console.log('err', err);
            reject(err)
          })
        })
      }else{
        reject('page valid err')
      }
    })
  }
  return wxp.request2(args)
}

export default wxp

6.效果

#yyds干货盘点#【愚公系列】2022年12月 微信小程序-小程序登录面板功能实现