Home  >  Article  >  WeChat Applet  >  A brief discussion on how to ensure that each page of the mini program is logged in

A brief discussion on how to ensure that each page of the mini program is logged in

青灯夜游
青灯夜游forward
2021-12-27 10:23:542202browse

How does the WeChat applet ensure that every page has been logged in? This article will introduce you to the method of mini program to ensure that every page is logged in. I hope it will be helpful to you!

A brief discussion on how to ensure that each page of the mini program is logged in

In a WeChat applet, there is a home page, a personal page, some list pages, detail pages, etc. Most of these pages can be shared. When the shared page is opened by another user, how does this page ensure that the user is logged in?

There are many solutions on the Internet that add an interception to the request encapsulation. If there is no token, first call the login request to obtain the token, and then continue. There is nothing wrong with this solution. Just pay attention to one thing. When multiple requests are triggered on a page at the same time, after all requests are intercepted, they are placed in an array. After successfully obtaining the token, just traverse the array one request at a time.

But this requirement is a little more complicated. For example, chain convenience store applet, most pages need to have a store (because it is necessary to obtain the inventory, price, etc. of the current store products based on the store). This store is based on the current store. Positioning is obtained by calling the background interface. At this time, it would be too troublesome to encapsulate it in the request.

Solution

First of all, we noticed that logging in, getting the position and our page request are asynchronous, we need to ensure that the page request It is after logging in and obtaining positioning, but if we write it again for every page, the maintainability will be too poor. So we can extract a way to do this. So the code is like this:

const app = getApp()
Page({
  data: {
    logs: []
  },
  onLoad() {
    app.commonLogin(()=>{
        // 处理页页面请求
    })
  }
})

Doing this seems to solve our problem, but think about it again, if you want to do more, such as unified processing of onShareAppMessage for each page, but I I don’t want to write it again on every page. In addition, I want to implement a watch for each page myself. How to do it?

Further solution

We can see that the WeChat applet, each page is a Page(), then we can give this Page Adding a layer of shell outside, we can have a MyPage to replace this Page. Without further ado, here is the code:

tool.js Related code

/**
   * 处理合并参数
   */
  handlePageParamMerge(arg) {
    let numargs = arg.length; // 获取被传递参数的数值。
    let data = {}
    let page = {}
    for (let ix in arg) {
      let item = arg[ix]
      if (item.data && typeof (item.data) === 'object') {
        data = Object.assign(data, item.data)
      }
      if (item.methods && typeof (item.methods) === 'object') {
        page = Object.assign(page, item.methods)
      } else {
        page = Object.assign(page, item)
      }
    }
    page.data = data
    return page
  }

  /***
   * 合并页面方法以及数据, 兼容 {data:{}, methods: {}} 或 {data:{}, a:{}, b:{}}
   */
  mergePage() {
    return this.handlePageParamMerge(arguments)
  }

  /**
   * 处理组件参数合并
   */
  handleCompParamMerge(arg) {
    let numargs = arg.length; // 获取被传递参数的数值。
    let data = {}
    let options = {}
    let properties = {}
    let methods = {}
    let comp = {}
    for (let ix in arg) {
      let item = arg[ix]
      // 合并组件的初始数据
      if (item.data && typeof (item.data) === 'object') {
        data = Object.assign(data, item.data)
      }
      // 合并组件的属性列表
      if (item.properties && typeof (item.properties) === 'object') {
        properties = Object.assign(properties, item.properties)
      }
      // 合组件的方法列表
      if (item.methods && typeof (item.methods) === 'object') {
        methods = Object.assign(methods, item.methods)
      }
      if (item.options && typeof (item.options) === 'object') {
        options = Object.assign(options, item.options)
      }
      comp = Object.assign(comp, item)
    }
    comp.data = data
    comp.options = options
    comp.properties = properties
    comp.methods = methods
    return comp
  }

  /**
   * 组件混合 {properties: {}, options: {}, data:{}, methods: {}}
   */
  mergeComponent() {
    return this.handleCompParamMerge(arguments)
  }

  /***
   * 合成带watch的页面
   */
  newPage() {
    let options = this.handlePageParamMerge(arguments)
    let that = this
    let app = getApp()

    //增加全局点击登录判断
    if (!options.publicCheckLogin){
      options.publicCheckLogin = function (e) {
        let pages = getCurrentPages()
        let page = pages[pages.length - 1]
        let dataset = e.currentTarget.dataset
        let callback = null

        //获取回调方法
        if (dataset.callback && typeof (page[dataset.callback]) === "function"){
          callback = page[dataset.callback]
        }
        // console.log('callback>>', callback, app.isRegister())
        //判断是否登录
        if (callback && app.isRegister()){
          callback(e)
        }
        else{
          wx.navigateTo({
            url: '/pages/login/login'
          })
        }
      }
    }

    const { onLoad } = options
    options.onLoad = function (arg) {
      options.watch && that.setWatcher(this)
      onLoad && onLoad.call(this, arg)
    }

    const { onShow } = options
    options.onShow = function (arg) {
      if (options.data.noAutoLogin || app.isRegister()) {
        onShow && onShow.call(this, arg)
        //页面埋点
        app.ga({})
      }
      else {
        wx.navigateTo({
          url: '/pages/login/login'
        })
      }
    }

    return Page(options)
  }

  /**
   * 合成带watch等的组件
   */
  newComponent() {
    let options = this.handleCompParamMerge(arguments)
    let that = this
    const { ready } = options
    options.ready = function (arg) {
      options.watch && that.setWatcher(this)
      ready && ready.call(this, arg)
    }
    return Component(options)
  }

  /**
    * 设置监听器
    */
  setWatcher(page) {
    let data = page.data;
    let watch = page.watch;
    Object.keys(watch).forEach(v => {
      let key = v.split('.'); // 将watch中的属性以'.'切分成数组
      let nowData = data; // 将data赋值给nowData
      for (let i = 0; i < key.length - 1; i++) { // 遍历key数组的元素,除了最后一个!
        nowData = nowData[key[i]]; // 将nowData指向它的key属性对象
      }

      let lastKey = key[key.length - 1];
      // 假设key===&#39;my.name&#39;,此时nowData===data[&#39;my&#39;]===data.my,lastKey===&#39;name&#39;
      let watchFun = watch[v].handler || watch[v]; // 兼容带handler和不带handler的两种写法
      let deep = watch[v].deep; // 若未设置deep,则为undefine
      this.observe(nowData, lastKey, watchFun, deep, page); // 监听nowData对象的lastKey
    })
  }

  /**
   * 监听属性 并执行监听函数
   */
  observe(obj, key, watchFun, deep, page) {
    var val = obj[key];
    // 判断deep是true 且 val不能为空 且 typeof val===&#39;object&#39;(数组内数值变化也需要深度监听)
    if (deep && val != null && typeof val === &#39;object&#39;) {
      Object.keys(val).forEach(childKey => { // 遍历val对象下的每一个key
        this.observe(val, childKey, watchFun, deep, page); // 递归调用监听函数
      })
    }
    var that = this;
    Object.defineProperty(obj, key, {
      configurable: true,
      enumerable: true,
      set: function (value) {
        if (val === value) {
          return
        }
        // 用page对象调用,改变函数内this指向,以便this.data访问data内的属性值
        watchFun.call(page, value, val); // value是新值,val是旧值
        val = value;
        if (deep) { // 若是深度监听,重新监听该对象,以便监听其属性。
          that.observe(obj, key, watchFun, deep, page);
        }
      },
      get: function () {
        return val;
      }
    })
  }

Page code:

app.tool.newPage({
  data: {
    // noAutoLogin: false
  },
  onShow: function () {
    // 在这里写页面请求逻辑
  }
}

Finally

The code has been running online for a long time. You can add it according to your needs through the newPage package in the tool. In short, I am here to provide an idea. If you have a better idea, please share it.

[Related learning recommendations: 小program development tutorial]

The above is the detailed content of A brief discussion on how to ensure that each page of the mini program is logged in. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete