摘要: 小程序开发技巧

Fundebug经授权转载,版权归原作者所有。

在原生开发小程序的过程中,发现有多个页面都使用了几乎完全一样的逻辑。由于小程序官方并没有提供 Mixins 这种代码复用机制,所以只能采用非常不优雅的复制粘贴的方式去“复用”代码。随着功能越来越复杂,靠复制粘贴来维护代码显然不科学,于是便寻思着如何在小程序里面实现 Mixins。

什么是 Mixins

Mixins 直译过来是“混入”的意思,顾名思义就是把可复用的代码混入当前的代码里面。熟悉 VueJS 的同学应该清楚,它提供了更强大了代码复用能力,解耦了重复的模块,让系统维护更加方便优雅。

先看看在 VueJS 中是怎么使用 Mixins 的。

// 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 的方法了。

明白了什么是 Mixins 以后,便可开始着手在小程序里面实现了。

Mixins 的机制

Mixins 也有一些小小的细节需要注意的,就是关于生命周期事件的执行顺序。在上一节的例子中,我们在 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 的 log,再输出来自组件的 log。

除了生命周期函数以外,再看看对象属性的混入结果:

// 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 中,会把来自 Mixins 和组件的对象属性当中的内容(如 data, methods等)混合,以确保两边的数据都同时存在。

经过上述的验证,我们可以得到 VueJS 中关于 Mixins 运行机制的结论:

  1. 生命周期属性,会优先执行来自 Mixins 当中的,后执行来自组件当中的。
  2. 对象类型属性,来自 Mixins 和来自组件中的会共存。

但是在小程序中,这套机制会和 VueJS 的有一点区别。在小程序中,自定义的方法是直接定义在 Page 的属性当中的,既不属于生命周期类型属性,也不属于对象类型属性。为了不引入奇怪的问题,我们为小程序的 Mixins 运行机制多加一条:

  1. 小程序中的自定义方法,优先级为 Page > Mixins,即 Page 中的自定义方法会覆盖 Mixins 当中的。

代码实现

在小程序中,每个页面都由 Page(options) 函数定义,而 Mixins 则作用于这个函数当中的 options 对象。因此我们实现 Mixins 的思路就有了——劫持并改写 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)
}

原理很简单,关键的地方在于 merge() 函数。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 使用

  1. 在小程序的 app.js 里引入 mixins.js

    require('./mixins.js')
  2. 撰写一个 myMixin.js

    module.exports = {
    data: { someData: 'myMixin' },
    onShow () { console.log('Log from mixin!') }
    }
  3. page/index/index.js 中使用

    Page({
    mixins: [require('../../myMixin.js')]
    })

大功告成!此时小程序已经具备 Mixins 的能力,对于代码解耦与复用来说将会更加方便。

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家免费试用!

在小程序中实现 Mixins 方案的更多相关文章

  1. 微信小程序中同步 异步的使用

    https://www.jianshu.com/p/e92c7495da76   微信小程序中使用Promise进行异步流程处理 https://www.cnblogs.com/cckui/p/102 ...

  2. WePY 在手机充值小程序中的应用与实践

    wepyjs 发布了两个月了,中间经历了很多版本更新,也慢慢开始有一些用户选择 wepyjs 作为开发框架来开发小程序,比如一些线上小程序. 以及一些来自网上的 wepyjs 的相关资源: demo源 ...

  3. 一招解决微信小程序中的H5缓存问题

    一招解决微信小程序中的H5缓存问题1.问题描述开发过程中,为了更新代码方便,往往会在小程序中嵌入H5页面.但问题来了,小程序原生代码更新版本后,简单的从微信中删除或者代码强刷就可以解决缓存问题,但小程 ...

  4. 在微信小程序中使用 echarts 图片-例 折线图

    首先进入echarts官方[https://echarts.apache.org/handbook/zh/get-started/].这边只需要在小程序中简单应用一下echarts折线图 所以不需要把 ...

  5. 网页或微信小程序中使元素占满整个屏幕高度

    在项目中经常要用到一个容器元素占满屏幕高度和宽度,然后再在这个容器元素里放置其他元素. 宽度很简单就是width:100% 但是高度呢,我们知道的是height:100%必须是在父元素的高度给定了的情 ...

  6. 微信小程序中rpx与rem单位使用

    原作者: 小小小   来自: 授权地址 本文讲解rpx和rem应用于微信小程序,如果你还没有入门,建议先从下面看起: 微信小程序官方文档web app变革之remrpx单位官方文档rpx单位基础介绍 ...

  7. 微信小程序中在swiper-item中遍历循环添加多个数据内容(微信小程序交流群:604788754)

    在小程序中为了实现一个<swiper-item>中添加多个内容重复的标签,那就需要使用wx:for循环.如果按小程序的简易教程,循环加在block中,而swiper-item放在里面.所有 ...

  8. 开发微信小程序中SSL协议的申请、证书绑定、TLS 版本处理等

    在上篇随笔<基于微信小程序的系统开发准备工作>介绍了开发微信小程序的一些前期的架构设计.技术路线 .工具准备等方面内容,本篇随笔继续这个步骤,逐步介绍我们实际开发过程中对SSL协议的申请及 ...

  9. 在微信小程序中使用富文本转化插件wxParse

    在微信小程序中我们往往需要展示一些丰富的页面内容,包括图片.文本等,基本上要求能够解析常规的HTML最好,由于微信的视图标签和HTML标签不一样,但是也有相对应的关系,因此有人把HTML转换做成了一个 ...

随机推荐

  1. SysML——AI-Sys Spring 2019

    AI-Sys Syllabus Projects Grading AI-Sys Spring 2019 When: Mondays and Wednesdays from 9:30 to 11:00 ...

  2. Windbg Locals(局部变量)窗口的使用

    在WinDbg中,可以通过输入命令.使用“局部变量”窗口或使用“监视”窗口查看局部变量.局部变量窗口显示当前作用域中的本地变量的所有信息. 如何打开Locals窗口 通过菜单View--->Lo ...

  3. Educational Codeforces Round 57 (Rated for Div. 2) C 正多边形 + 枚举

    https://codeforces.com/contest/1096/problem/C 题意 问是否存在一正多边形内三点构成的角度数为ang,若存在输出最小边数 题解 三点构成的角是个圆周角,假设 ...

  4. Educational Codeforces Round 70 题解

    噩梦场. 题目出奇的难,好像一群外国老哥看 A 看着看着就哭了-- A 找到 \(b\) 最低的 \(1\),这个 \(1\) 肯定要跟 A 中的一个 \(1\) 搭配,而且是能搭配的 \(1\) 中 ...

  5. [LeetCode] 904. Fruit Into Baskets 水果装入果篮

    In a row of trees, the i-th tree produces fruit with type tree[i]. You start at any tree of your cho ...

  6. [LeetCode] 786. K-th Smallest Prime Fraction 第K小的质分数

    A sorted list A contains 1, plus some number of primes.  Then, for every p < q in the list, we co ...

  7. Spring Cloud Alibaba整合Sentinel流控

    前面我们都是直接通过集成sentinel的依赖,通过编码的方式配置规则等.对于集成到Spring Cloud中阿里已经有了一套开源框架spring-cloud-alibaba,就是用于将一系列的框架成 ...

  8. 从excel中转存sql

    1.pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...

  9. Nodejs操作MySQL数据库

    https://github.com/mysqljs/mysql   如何用nodejs操作MySql数据呢,其实写法还是简单的, 1.开始在你的node项目中 npm install mysql - ...

  10. VUE引入jq bootstrap 之终极解决方案(测试)

    初入VUE遇见的一些问题,在网上找了些方法,再根据自己的实际项目解决的问题写得此文,,希望对你有所帮助. vue-cli快速构建项目以及引入boostrap.jq各种插件配置 vue-cli脚手架工具 ...