小程序登录弹框

需求描述 源码地址

  1. 登录弹框样式实现。
  2. 在用户发起操作时(如:点击某个按钮)检测用户登录,如未登录,记录用户操作,弹出登录框。
  3. 用户登录成功后自动用户的上次操作。
  4. 操作流程 (开始)用户点击行为 --> 验证是否登录 --> 已登录,返回成功回调(结束),未登录,弹出登录框 --> 用户点击登录 --> 登录完成,根据记忆重复用户开始位置的点击行为

所需知识点

  1. behaviors混入
  2. 小程序获取自定义组件实例

实现

  1. 实现登录弹框组件 在根目录创建components文件夹,新建login-box组件,注意这里引用了vant的弹框,可以替换为自己的ui库弹框。

在这里插入图片描述
login-box/index.js文件中的$show方法记录当前调用位置的this实例、触发弹框的方法、方法的参数,以便于在登录成功后重新执行触发弹框的方法 来记忆用户的上次操作

import {
    
    SwwComponent} from "../../mixins/component";
import {
    
    wxLogin} from "../../utils/wxPromise";

SwwComponent({
    
    
    data: {
    
    
        userInfoVisible: false,
    },
    pageLifetimes: {
    
    
        show() {
    
    
            if ((this.data.userInfoVisible || this.data.phoneVisible) && this.$isLogin()) {
    
    
                this.$close()
            }
        }
    },
    methods: {
    
    
        //关闭弹框
        $close() {
    
    
            this.setData({
    
    
                userInfoVisible: false,
                phoneVisible: false
            })
        },
        //打开弹框
        $show(currentThis, funName, params) {
    
    
            this.currentThis = currentThis
            this.loginFunName = funName
            this.loginFunParams = params
            this.setData({
    
    
                userInfoVisible: true
            })
        },
        //获取用户信息
        $getUserInfo(e) {
    
    
            wx.nextTick(() => {
    
    
                if (e.detail.errMsg === 'getUserInfo:ok') {
    
     //用户同意授权
                    this.$close()
                    this.$loginByApi(e.detail.userInfo)
                } else {
    
     //用户拒绝授权

                }
            })
        },
        //通过接口获取用户信息
        $loginByApi(info) {
    
    
            console.log(info);
            //TODO 这里模拟登录成功
            wx.showLoading({
    
    mask: true})
            setTimeout(() => {
    
    
                wxLogin().then(code => {
    
    
                    wx.hideLoading()
                    wx.showToast({
    
    
                        title: '登录成功'
                    })
                    wx.setStorageSync('token', code)
                    this.$loginSuccess()
                })
            }, 1000)
        },
        $loginSuccess() {
    
    
            this.currentThis[this.loginFunName](this.loginFunParams)
            wx.nextTick(() => {
    
    
                delete this.currentThis
                delete this.loginFunName
                delete this.loginFunParams
            })
        }
    }
});
  1. 重构页面Page,Compoent,这里使用的是vant封装的Compoent,并根据需求新增了一下自己的方法和属性。在项目根目录创建mixins文件夹,新建component.js basic.js。component.js根据习惯重新命名了小程序的一些页面属性名,如:properties --> props,behaviors --> mixins…。basic.js混入了一些常用方法,这里登录组件用到的有两个 $isLogin返回登录状态, $login验证是否有登录,如果登录则返回Promise.resolve,如果未登录,则拉起登录弹框。
//basic.js
export const basic = Behavior({
    
    
  methods: {
    
    
    $emit(name, detail, options) {
    
    
      this.triggerEvent(name, detail, options);
    },
    set(data) {
    
    
      this.setData(data);
      return new Promise((resolve) => wx.nextTick(resolve));
    },
    /**
     * 验证是否登录
     */
    $isLogin() {
    
    
      let token = wx.getStorageSync('token')
      return !!token
    },
    /**
     * 验证是否登录,若未登录,则打开登录弹框
     * funName 登录成功的回调方法
     * params 登陆成功的回调参数
     */
    $login(funName = '', params = {
    
    }) {
    
    
      return new Promise((resolve, reject) => {
    
    
        if (this.$isLogin()) {
    
    
          resolve()
        } else {
    
    
          try {
    
    
            let pages = getCurrentPages()
            pages[pages.length - 1].selectComponent('#login-box').$show(this, funName, params)
          } catch (e) {
    
    
            wx.showToast({
    
    
              title: '请在页面引入登录组件'
            })
            reject(e)
          }
          reject()
        }
      })
    },
  },
});
//component.js
import {
    
     basic } from './basic';
function mapKeys(source, target, map) {
    
    
  Object.keys(map).forEach((key) => {
    
    
    if (source[key]) {
    
    
      target[map[key]] = source[key];
    }
  });
}
function SwwComponent(vantOptions) {
    
    
  const options = {
    
    };
  mapKeys(vantOptions, options, {
    
    
    data: 'data',
    props: 'properties',
    mixins: 'behaviors',
    methods: 'methods',
    beforeCreate: 'created',
    created: 'attached',
    mounted: 'ready',
    destroyed: 'detached',
    classes: 'externalClasses',
    watch: 'observers',
    options: 'options',
    lifetimes: 'lifetimes',
    pageLifetimes: 'pageLifetimes',
  });
  // add default externalClasses
  options.externalClasses = options.externalClasses || [];
  options.externalClasses.push('custom-class');
  // add default behaviors
  options.behaviors = options.behaviors || [];
  options.behaviors.push(basic);
  // add relations
  const {
    
     relation } = vantOptions;
  if (relation) {
    
    
    options.relations = relation.relations;
    options.behaviors.push(relation.mixin);
  }
  // map field to form-field behavior
  if (vantOptions.field) {
    
    
    options.behaviors.push('wx://form-field');
  }
  // add default options
  options.options = {
    
    
    multipleSlots: true,
    addGlobalClass: true,
  };
  Component(options);
}
export {
    
     SwwComponent };

  1. 全局引入登录弹框,在页面中(注意这里,假如页面A引入了组件B,组件B又引入了组件C···,切组件A B C···都使用了登录验证,无需在每个组件都引入登录弹框组件,仅需在页面A使用弹框组件即可)使用登录弹框login-box。调用登录弹框的操作如下:
import {
    
    SwwComponent} from "../../../../mixins/component";

SwwComponent({
    
    
    methods: {
    
    
        onClick(e) {
    
    
            this.$login('onClick', e).then(() => {
    
    
                console.log(e);
                console.log('登录成功');
            })
        }
    }
})

猜你喜欢

转载自blog.csdn.net/qq_40026668/article/details/114406257
今日推荐