原理

重写小程序的Page方法,合并Page方法的默认参数中的属性、方法和生命周期等

原则

属性和方法会进行覆盖,当前页面声明的属性和方法会覆盖mixin中的属性和方法,生命周期函数不会进行覆盖,执行顺序为全局mixin>单独mixin>当前页生命周期函数

具体操作

  • 创建一个mixins.js
// 把本来的Page方法缓存下来
const ori_page = Page
const lifecycle = ['onLoad', 'onReady', 'onShow', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage', 'onPageScroll']

let globalMixin = null // 全局混入
// 全局mixin方法
wx.mixin = config => {
    if (isType(config, 'object')) {
        globalMixin = config
    }
}
// 重写Page方法
Page = config => {
    let mixins = config.mixins
    // 加入全局mixin,首先执行全局的
    if(globalMixin) {
        (mixins || (mixins = [])).unshift(globalMixin)
    }
    if(isType(mixins, 'array') && mixins.length > 0) {
        // 删除config的mixins属性
        Reflect.deleteProperty(config, 'mixins')
        // 把mixins中的东西,混入到config里面去
        merge(mixins, config)
    }
    // 调用默认的Page方法进行初始化
    ori_page(config)
}

function merge(mixins, config) {
    mixins.forEach(mixin => {
        if(isType(mixin, 'object')) {
            Object.keys(mixin).forEach(key => {
                if(key === 'data') {
                    // 合并data
                    config.data = Object.assign({},mixin[key],config[key])
                }else if (lifecycle.includes(key)) {
                    // 缓存当前页面的生命周期函数
                    let ori_lifecycle = config[key]
                    config[key] = function() {
                        // arguments对象转数组
                        let arg = Array.prototype.slice.call(arguments)
                        // 执行minxin的生命周期函数
                        mixin[key].call(this, arg)
                        // 执行当前页的生命周期函数
                        ori_lifecycle && ori_lifecycle.call(this, arg)
                    }
                }else {
                    // 合并methods
                    config[key] = mixin[key]
                }
            })
        }
    })
}

//判断类型函数
function isType(target, type) {
    let targetType = Object.prototype.toString.call(target).slice(8, -1).toLowerCase()
    type = type.toLowerCase()
    return targetType === type
}
  • 引入mixins.js
// aap.js
import './mixins'
  • 声明一个mixin
module.exports = {
    test: {
        data: {
            msg: 'Hello world'
        }
    }
}
  • 使用
import {test} from './someMixins'
Page({
    mixins: [test]
})

yingmhd
67 声望4 粉丝

路漫漫其修远兮,吾将上下而求索