小程序原生开发中实现mixins代码复用机制的解决方案
在小程序原生开发的过程中,我发现不同的页面使用了几乎相同的逻辑。由于小程序官方并没有提供像 mixins 这样的代码重用机制,所以“重用”代码的唯一方法就是通过非常不优雅的复制粘贴方法。随着功能越来越复杂,通过复制粘贴来维护代码显然是不科学的,于是我开始思考如何在小程序中实现mixin。
什么是 Mixins
Mixin 的字面意思是“混合”。顾名思义,这意味着将可重用代码混合到当前代码中。熟悉VueJS的同学应该知道,它提供了更强大的代码复用能力,解耦了重复模块,让系统维护更加方便优雅。
我们先来看看如何在 VueJS 中使用 mixin。
// define a mixin object
var myMixin = {
created: function () {
this.hello()
},
methods: {
hello: function () {
console.log('hello from mixin!')
}
}
}
// define a component that uses this mixin
var Component = Vue.extend({
mixins: [myMixin]
})
var component = new Component() // => "hello from mixin!"
复制代码
上面的代码中,首先定义了一个名为myMixin
的对象,该对象定义了一些生命周期函数和方法。然后将它们直接注入到mixins新建的组件中:[myMixin]
。这时,新创建的组件就会有myMixin
的方法。
了解了什么是 mixin 后,就可以开始将它们实现到小程序中了。
Mixin 的机制
Mixin 还有一些小细节需要注意,那就是生命周期事件的执行顺序。在上一节的例子中,我们在myMixin
中定义了一个created()
方法,它是VueJS中的生命周期事件。如果我们在新组件Component
中也定义一个created()
方法,那么执行结果会是什么呢?
var Component = Vue.extend({
mixins: [myMixin],
created: function () {
console.log('hello from Component!')
}
})
var component = new Component()
// =>
// Hello from mixin!
// Hello from Component!
复制代码
可以看到运行结果是先输出mixin的日志,然后输出组件的日志。
除了生命周期功能之外,我们再看一下对象属性的混合结果:
// define a mixin object
const myMixin = {
data () {
return {
mixinData: 'data from mixin'
}
}
}
// define a component that uses this mixin
var Component = Vue.extend({
mixins: [myMixin],
data () {
return {
componentData: 'data from component'
}
},
mounted () {
console.log(this.$data)
}
})
var component = new Component()
复制代码
在VueJS中,mixin和组件的对象属性的内容(如data❓、方法
等)混合使用,保证双方数据同时存在。
经过上面的验证,我们可以得到VueJS中mixins的运行机制的结论:
- 生命周期属性是先由mixins执行,然后由组件执行。
- mixin 和组件的对象类型属性将共存。
但是在小程序中,这个机制会和VueJS有点不同。在小程序中,自定义方法直接定义在页面的属性中,它既不是生命周期类型属性,也不是对象类型属性。为了不引入奇怪的问题,我们在小程序的 mixins 运行机制中额外添加一行:
- 小程序中自定义方法的优先级为 Page > Mixins,即自定义方法对 Page 进行覆盖Mixins 中的那些。
代码实现
小程序中,每个页面由 新建一个 原理很简单,关键点就是 即可完成!此时小程序已经具备了mixins的能力,更方便代码解耦和复用。 作者:JrainPage(Options)
函数定义,mixin作用于Options对象。所以我们实现mixin的思路就是劫持函数
Page
并重写,最后再次释放。 mixins.js
文件:// 保存原生的 Page 函数
const originPage = Page
Page = (options) => {
const mixins = options.mixins
// mixins 必须为数组
if (Array.isArray(mixins)) {
delete options.mixins
// mixins 注入并执行相应逻辑
options = merge(mixins, options)
}
// 释放原生 Page 函数
originPage(options)
}
复制代码
fusion()♶❝。函数
中使用 merge
是小程序Mixins运行机制的具体实现,完全按照上一节总结的三个结论来进行。 // 定义小程序内置的属性/方法
const originProperties = ['data', 'properties', 'options']
const originMethods = ['onLoad', 'onReady', 'onShow', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage', 'onPageScroll', 'onTabItemTap']
function merge (mixins, options) {
mixins.forEach((mixin) => {
if (Object.prototype.toString.call(mixin) !== '[object Object]') {
throw new Error('mixin 类型必须为对象!')
}
// 遍历 mixin 里面的所有属性
for (let [key, value] of Object.entries(mixin)) {
if (originProperties.includes(key)) {
// 内置对象属性混入
options[key] = { ...value, ...options[key] }
} else if (originMethods.includes(key)) {
// 内置方法属性混入,优先执行混入的部分
const originFunc = options[key]
options[key] = function (...args) {
value.call(this, ...args)
return originFunc && originFunc.call(this, ...args)
}
} else {
// 自定义方法混入
options = { ...mixin, ...options }
}
}
})
return options
}
复制代码
Mixins 在小程序
app.js
中使用mixins.js
require('./mixins.js')
复制代码
Page({
mixins: [require('../../myMixin.js')]
})
复制代码
链接:https://juejin.im/post/5d0a07eb6fb9a07eba2c4142
来源:掘金
版权归作者所有。如需商业转载,请联系求作者授权。非商业转载请来源。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。