封装一个小程序的全局控制方法

376 阅读1分钟
const originApp = App
const originPage = Page

const noop = () => { }

const app = { }
const appKeys = [  'onLaunch', 'onShow', 'onHide',  'onError', 'onPageNotFound',  'onUnhandledRejection', 'onThemeChange']
appKeys.forEach((key) => app[key] = noop)

const page = { }
const pageKeys = [  'onLoad', 'onShow', 'onReady', 'onHide', 'onUnload',  'onPullDownRefresh', 'onReachBottom', 'onPageScroll',  'onResize', 'onTabItemTap']
pageKeys.forEach((key) => page[key] = noop)

const fillApp = (configs) => extend({ }, app, configs)
const fillPage = (configs) => extend({ }, page, configs)

function extend(target, ...extendObjs) {
  for (let i = 0; i < extendObjs.length; i++) {
    const currObj = extendObjs[i]
    for (const key in currObj) {
      target[key] = isObject(currObj[key]) ? extend(target[key] || { }, currObj[key]) : currObj[key]
    }
  }
  return target
}

function isObject(o) {
  return o && (
    o.constructor === Object ||
    Object.prototype.toString.call(o) === '[object Object]'
  )
}

function updateByPath(origin, path, value) {
  try {
    const target = path.replace(/]/g, '').replace(/\[/g, '.').split('.')
    const length = target.length

    let current = origin
    for (let i = 0; i < length; i++) {
      if (i == length - 1) {
        current[target[i]] = value
      } else {
        current = current[target[i]]
      }
    }
  } catch (err) {
    console.log(e)
  }
}

function resetApp(configs) {
  const { onLaunch, onHide } = fillApp(configs)

  const appConfigs = extend({ }, configs, {
    onLaunch() {
      const _ = this
      onLaunch.call(_)
    },
    onHide() {
      const _ = this
      onHide.call(_)
    },
    setData(obj) {
      if (!isObject(obj)) return;
      const _ = this
      for (let key in obj) {
        updateByPath(_.globalData, key, obj[key]);
      }
    },
    /**
     * [获取缓存数据]
     *
     * @param {String} key 缓存key
     * @example
     * setCookie('test')
     */
    setCookie(key, value) {
      try {
        if (typeof key != 'string') return
        wx.setStorageSync(key, value)
      } catch (err) { }
    },

    /**
     * [获取缓存数据]
     *
     * @param {String} key 缓存key
     * @example
     * getCookie('test')
     */
    getCookie(key) {
      let cookie
      try {
        cookie = wx.getStorageSync(key)
      } catch (err) { }
      return cookie
    },

    /**
     * [获取一个十六进制的缓存时间戳]
     *
     * @param {Number} second 缓存时间(秒)
     * @example
     * cacheTime(5)
     */
    cacheTime(second) {
      return parseInt(
        (new Date()).getTime() /
        (1e3 * (Number(second) || 0.2))
      ).toString(16)
    }
  })

  originApp(appConfigs)
}

function resetPage(configs) {
  if (configs._ignore) {
    originPage(configs)
    return
  }

  const { onLoad, onShow, onReady, onHide } = fillPage(configs)

  const initConfigs = {
    onLoad(options) {
      const _ = this
      onLoad.call(_, options)
    },

    onShow(options) {
      const _ = this
      onShow.call(_, options)
    },

    onReady() {
      const _ = this
      onReady.call(_)
    },

    onHide() {
      const _ = this
      onHide.call(_)
    }
  }

  if (configs.onShareAppMessage) {
    configs._getShareConfigs = configs.onShareAppMessage
    const defaultShareConfigs = {
      title: '',
      imageUrl: '',
      path: '',
    }

    initConfigs.onShareAppMessage = function(ev) {
      const shareMessage = this._getShareConfigs(ev)
      const shareObj = extend({ }, shareMessage, {
        sharetype: ev.from == 'menu' ? '右上角菜单' : '页面按钮'
      })
      return extend({ }, defaultShareConfigs, shareObj)
    }
  }

  if (configs.onPageScroll) {
    let scrollTimer = false
    configs._onScrollFn = configs.onPageScroll
    initConfigs.onPageScroll = function (e) {
      const _ = this
      if (scrollTimer) clearTimeout(scrollTimer)
      scrollTimer = setTimeout(() => {
        configs._onScrollFn.call(_, e)
        clearTimeout(scrollTimer)
      }, 50)
    }
  }

  const pageConfigs = extend({ }, configs, initConfigs)
  originPage(pageConfigs)
}

App = resetApp
Page = resetPage