WeChat applet as a global login pop-up window

Requirement: On any page that needs to pop up login, the background returns the status code that needs to be logged in, pops up a login window to log in, and refreshes the current page. Process
: Because the WeChat applet cannot encapsulate a global component and call it globally through the method. Therefore, only one public component can be encapsulated, registered and mounted on the page that needs a pop-up window, and can be registered globally in app.json (there are problems here that will be mentioned later), and there is no need to register on the page that needs a pop-up window, just hang it directly Just load it.
Effect:
pop-up effect

1. The first step is to encapsulate the global pop-up window component

Note: The first pitfall of encapsulating the pop-up window component, I used the page-container component of the WeChat applet at that time, and used show to control the display and hiding of the pop-up window. In the case of global registration and subpackage, the applet An error will be reported,
Render layer error Component: Only one instance can exist.
which roughly means that the page-container component can only have one instance. This problem occurs when you log in to the package A page, set the token to expire, and then enter the page that needs to be logged in in package B. The pop-up window cannot pop up and will report this error.

popup window component code

<!--components/LoginPopup/LoginPopup.wxml-->

<!-- 这里就会出现上面的问题 -->
<!-- <page-container show="{
    
    {show}}" position="center" overlay-style="width:200rpx" custom-style="background:transparent;" z-index="99999"> -->
<!-- 解决方法,直接用view替换掉page-container,用wx:if控制显隐,效果是一样的 -->
<view class="container-box" wx:if="{
    
    {show}}">
  <view class="popup-box flex-c h--100 w--100">
    <view class="popup-content">
      <view class="br-10 bag-fff">
        <view class="popup-top flex flex-y ju-c pad-l-40">
          <text class="c-333 fs-20 wt-600">登录</text>
          <text class="c-ccc fs-16">Login</text>
        </view>
        <view class="popup-bot pad-20 box-bor mar-t-4">
          <button class="w--100 btn-style1 fs-14 flex-c bag-46D2A1 c-fff br-8 wt-400" bindtap="login">微信一键登录</button>
          <!-- <button class="w--100 btn-style1 fs-14 flex-c bag-46D2A1 c-fff br-8 wt-400"  open-type="getPhoneNumber" type="primary"
      bindgetphonenumber="onGetPhoneNumber">微信一键登录</button> -->
          <!-- <button class="w--100 btn-style2 fs-14 flex-c mar-t-16 bag-fff c-999 br-8 wt-400">手机号登录/注册</button> -->
          <view class="fs-10 flex al-c mar-t-18 line-1 c-ccc" bindtap="setAgree">
            <text wx:if="{
    
    {agree}}" class="iconfont icon-44xuanze-2 c-46D2A1 line-1 fs-12 mar-r-2"></text>
            <text wx:else class="iconfont icon-xuanzhong c-999 line-1 fs-12 mar-r-2"></text>
            <text>登录代表您已同意</text>
            <text class="c-46D2A1" data-type="1" catchtap="goWebView">xxx用户协议 、</text>
            <text class="c-46D2A1" data-type="2" catchtap="goWebView">隐私协议</text>
          </view>
        </view>
      </view>
      <view class="line mar-auto"></view>
      <image bindtap="closePopup" class="close-btn mar-auto" src="https://jmqfile.oss-cn-hangzhou.aliyuncs.com/admin/0/20221214/f92b62cc50174d9d8d412fe97ea19d4c.png" mode=""/>
    </view>
  </view>
</view>
<!-- </page-container> -->
// components/LoginPopup/LoginPopup.ts

// 引入刷新当前页面的公共方法,后面有讲到
import {
    
     refreshPage } from '../../utils/util'
Component({
    
    
   // 这里可有可无,因为碰到一个需求,在首页不需要一进来就弹出登录弹出,
   // 但是点击banner图跳到外部链接的时候需要登录,因此我加了一个属性isShow
  properties: {
    
    
    isShow:Number
  },
  data: {
    
    
    // 控制弹窗显隐的属性
    show: false
  },
  // 这里可以忽略,自己业务需求
  attached(){
    
    
    const {
    
    isShow} = this.data
    if(isShow){
    
    
      this.setData({
    
    
        show:isShow==1?true:false
      })
    }
  },
  methods: {
    
    
    // 跳转协议页面
    goWebView(e: WechatMiniprogram.TouchEvent) {
    
    
     ...
    },
    setAgree() {
    
    
      ...
    },
    closePopup() {
    
    
      this.setData({
    
    
        show: false
      })
    },
    // 登录
    login() {
    
    
      ...
    },
    // 获取用户信息
    async getUserInfo() {
    
    
      ...
      // 获取完用户信息之后,刷新当前页面
      // 看需求,也可以登录完成之后直接刷新当前页面
      refreshPage()
    }
  }
})

2. The second step is to register components globally

app.json

"usingComponents": {
    
    
    "LoginPopup": "./components/LoginPopup/LoginPopup"
  },

3. The third step is to mount it on the page where the pop-up window needs to be displayed

   // 这里要用class,用于获取组件节点
  <LoginPopup class="LoginPopup"></LoginPopup>

4. The fourth step is to encapsulate the public method of the control component

Put the method of controlling the display and concealment into the public method, introduce and call it where needed, such as putting it in the response interception
utils/index.ts

// 获取当前页面实例
function getContext() {
    
    
  const pages = getCurrentPages();
  return pages[pages.length - 1];
}
// 控制弹窗显隐方法
export function BadgePopup() {
    
    
  const options = {
    
    
    show: true,
  	dom: '.LoginPopup'
  };
  const page = getContext();
  const c= page .selectComponent(options.dom);
  if (!c) {
    
    
    console.warn(`未找到 ${
      
      options.dom} 节点,请确认 dom 是否正确`);
    return;
  }
  c.setData(options);
}

5. The fifth step is to encapsulate the public method of refreshing the current page

The method of refreshing the current page is usually called directly after the login is completed and the user information is obtained.

utils/index.ts

// 刷新当前页面
export function refreshPage() {
    
    
  // getContext() 和第四步使用的同一个方法
  const perpage = getContext()
  
  const keyList = Object.keys(perpage.options)
  if (keyList.length > 0) {
    
    //页面携带参数
    let keys = '?'
    keyList.forEach((item, index) => {
    
    
      index === 0 ? keys = keys + item + '=' + perpage.options[item] : keys + '&' + item + '=' + perpage.options[keys]
    })
    wx.reLaunch({
    
    
      url: '/' + perpage.route + keys
    })
  } else {
    
    //页面没有携带参数
    perpage.onLoad()
    // 也可以使用wx.reLaunch
  }
}

6. Summary

The best solution I can think of so far, please let me know if there is a better way

Guess you like

Origin blog.csdn.net/qq_45142260/article/details/128844351