Do Not Repeat Yourself

如何提高代码质量,方法有许多:抽象、模块、组件化,我认为它们的中心点都是——Do Not Repeat Yourself.

小程序组件化

我们先看看小程序自带的组件化能力:

  • 模板,通过 <import src="../name.wxml" /> 引入 ---- success
  • 样式,通过 @import 'name.wxss' 引入 ---- success
  • js ??? ---- fail

我们看到,微信小程序开发有一个很大的痛点,缺乏组件化能力,特别是在没有使用构建工具或第三方框架的情况下,稍不留神,就会充满大量重复的代码。

小程序提供了自定义组件( V1.6.3 才支持)

举个栗子。

小程序虽然提供了一些常用的组件——toast、loading等,但因需求不同,我们要实现自己的 popupnotifymodal等公共组件。这些自定义组件的共同点是:单个组件模板、事件大致一样,区别是每次使用组件时显示的内容不同。于是,我们在每个页面都能看到相似的代码,emm,已经产生了臭味道。

mixins

通过混入的方式,将组件方法、数据绑定到页面实例上,类似VUE mixins,不过,这里实现要更为简单:

function mixins(page, ...args) {
let data = args.reduce((res, item) => Object.assign(res, item.data), page.data || {}) Object.assign(page, ...args)
page.setData(data)
}

这样,在页面onLoad时,执行mixins(this, Component1, ...)就可以了。

写一个popup

现在开始写一个 popup组件,设计给的样式如下图:

除去布局和样式,应该如何设计数据模型?个人认为需要把握两点:职责分离、易于扩展。

第一步,分析哪些数据是不变的、可变的。

可变数据:标题、内容、按钮文字、按钮个数、点击按钮后续操作、蒙层是否可点

不变数据:点击蒙层、取消按钮隐藏popup,显示/隐藏popup事件

第二步,设计数据模型。

通过第一步的分析,我们可以抛开具体的业务逻辑,设计出popup的数据模型:

let popupModal = {
title: '',
content: '',
confirmButtonName: '确认',
cancelButtonName: '取消', show(),
hide(),
onConfirm(),
onCancel(),
}

使用面向对象可以轻松分离可变、不可变数据,生成所需数据模型:

class GeneratePopupModal {
constructor(options) {
this.setParams(options)
} setParams({
title,
content,
confirmButtonName,
cancelButtonName,
success,
} = {}) {
this.title = title || this.title
this.content = content || this.content
this.confirmButtonName = confirmButtonName || this.confirmButtonName
this.cancelButtonName = cancelButtonName || this.cancelButtonName this.success = success
}
show() {
return Promise.resolve(this.__show = true)
}
hide() {
return Promise.resolve(this.__show = false)
}
onConfirm() {
return this.hide()
.then(() => {
if(this.success) return this.success({confirm: true})
})
}
onCancel() {
return this.hide()
.then(() => {
if(this.success) return this.success({cancel: true})
})
}
}

第三步,生成数据渲染组件。

为了使popup组件保持简单,只对外暴露三个方法:

  • $popup(opts) ---- 根据参数生成组件数据并显示 popup
  • tapPopupConfirmButton() ---- 点击 popup 确认按钮
  • tapPopupCancelButton() ---- 点击 popup 取消按钮
const GeneratePopupModal = require('./generatePopupModal')
const defalut = {
title: '管家提示',
content: '抱歉,我们遇到一点问题,请稍后再试',
confirmButtonName: '确认'
} let Popup = null module.exports = {
$popup(options={}) {
/**
* 每次使用新建实例,避免状态共享
* 通过私有 __show 控制 popup.show,实现组件 popup 的显示和隐藏
*/
Popup = new GeneratePopupModal(defalut) Object.defineProperty(Popup, '__show', {
configurable: true,
set: v => {
Popup.show = v
this.setData({popupModal: Popup})
}
})
return new Promise((resolve, reject) => {
Popup.setParams(
Object.assign({}, {success: resolve, fail: reject}, options)
)
Popup.__show = true
})
},
tapPopupConfirmButton() {
Popup.onConfirm()
},
tapPopupCancelButton() {
Popup.onCancel()
},
}

第四步,引入、使用组件

在上面mixins部分,介绍了如何引入组件。那么,怎么使用它呢?这里提供一个栗子:

this.$popup({ // 根据传参生成数据、显示 popup
title: '删除行程',
content: '确认删除此行程?删除后将不可恢复。',
confirmButtonName: '删除',
cancelButtonName: '我再想想',
}).then(({confirm, cancel}) => { // 分别表示点击了确定、取消按钮
if(confirm) { // 点击删除(确定)按钮后续操作
return r4251({
id: item.productid,
type: item.type
})
.then(res => this.__fetchCartList())
.catch(e => {
this.$popup() // 显示默认数据的 popup console.error('[cart/list.js] #tapDeleteCart r4251 error: ', e)
})
}
})

总结

至此,popup组件基本完成了,但这种方式依然存在很大的漏洞:

  • mixins 方式混入组件数据/方法,极易造成命名冲突。通过命名空间解决
  • 如果组件有 data 对象,那么页面销毁(unLoad)后,页面数据依然常驻内存。通过导出函数对象解决

虽然上面的解决方案并不十分理想难道不是非常别扭?,但好在足够简洁、实用,也基本实现了设计预期。

期待更好的实现思路......

.

微信小程序组件化实践的更多相关文章

  1. 【腾讯Bugly干货分享】打造“微信小程序”组件化开发框架

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/2nQzsuqq7Avgs8wsRizUhw 作者:Gc ...

  2. 微信小程序组件化开发框架WePY

    wepy-CLI 安装 npm install -g wepy-cli wepy init standard my-project https://github.com/Tencent/wepy 特性 ...

  3. 小程序组件化框架 WePY 在性能调优上做出的探究

    作者:龚澄 导语 性能调优是一个亘古不变的话题,无论是在传统H5上还是小程序中.因为实现机制不同,可能导致传统H5中的某些优化方式在小程序上并不适用.因此必须另开辟蹊径找出适合小程序的调估方式. 本文 ...

  4. 小程序组件化开发框架---wepy 项目创建

    wepy是一个优秀的微信小程序组件化框架,突破了小程序的限制,支持了npm包加载以及组件化方案.这里就以我个人的经历讲下怎么创建wepy项目. 1.首先 在桌面(自己选定目录下)新建一个文件夹,注意需 ...

  5. WePY | 小程序组件化开发框架

    资源连接: WePY | 小程序组件化开发框架 WePYAWESOME 微信小程序wepy开发资源汇总 文档 GITHUB weui WebStorm/PhpStorm 配置识别 *.wpy 文件代码 ...

  6. 微信小程序组件设计规范

    微信小程序组件设计规范 组件化开发的思想贯穿着我开发设计过程的始终.在过去很长一段时间里,我都受益于这种思想. 组件可复用 - 减少了重复代码量 组件做为抽离的功能单元 - 方便维护 组件作为temp ...

  7. 微信小程序组件学习 -- 注册页面

    微信小程序组件使用手册地址: 1. 百度搜索"微信公众平台",扫码登录之后,点击帮助文档里面的普通小程序. 2. 接着选择"开发"-->"组件& ...

  8. 初尝微信小程序开发与实践

    这可能是一个java程序员最不务正业的一次分享了. 小程序的火热相信不用我多说了,年初的时候老婆去浦东某达面试,甚至都被问有没有小程序测试经验.俨然小程序成为了互联网公司自PC,WAP,安卓,IOS之 ...

  9. 微信小程序(组件demo)以及预览方法:(小程序交流群:604788754)

    1. 获取微信小程序的 AppID 登录 https://mp.weixin.qq.com ,就可以在网站的"设置"-"开发者设置"中,查看到微信小程序的 Ap ...

随机推荐

  1. 白盒静态自动化测试工具:PMD使用指南

    参考文献:http://www.oschina.net/p/pmd/http://www.cnblogs.com/flyme/archive/2011/09/09/2172548.htmlhttp:/ ...

  2. JAVA Get UUID

    UUID是通用唯一标识码(Universally Unique Identifier),通过开源软件基金会(OSF)设立的一种算法生成.它的主要作用就是保证生成的字符串在同一时空中所有机器上都是唯一的 ...

  3. kerberos认证的步骤,学习笔记

    .KDC,uname,upwd -x算法=>authticator 暗号 .KDC ->uname,pwd->x1算法->解密authticator 确认客户端身份->生 ...

  4. cmd里面怎么复制粘贴

    不要打开快速编辑模式,他只能复制粘贴cmd里面的内容 其实用标记即可. 右键选择标记,然后框选内容后右键就复制了 然后再右键粘贴就行了.

  5. W-D-S-UART编程

    1.协议原理 2.原理框图 3.开发板底板与核心板图 4.开始配置寄存器 a).使相应I/O引脚配置为UART引脚 b).配置数据发送模式 c).设置为中断或查询模式 d).使能串口缓存 e).流量控 ...

  6. Binary search tree or not

    https://github.com/Premiumlab/Python-for-Algorithms--Data-Structures--and-Interviews/blob/master/Moc ...

  7. 解决sea_born和matplotlib画图中文显示的问题

    #以下解决mtpl中文显示问题 from pylab import * mpl.rcParams['font.sans-serif'] = ['SimHei'] #以下解决seaborn中文编码报错问 ...

  8. js模态窗口返回值(table)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. 编写属于自己的linux命令

    开篇: 问题和解决思路 在使用一些基础IDE时,工具经常会在我们建立特定文件时给我们一个已经有了一些特定代码的模板文件,但是在linux开发时,没有这样的IDE,怎么办?虽然代码量不是很多,但是能一次 ...

  10. day08(异常处理,创建异常,finally,throws和throw的区别)

    异常处理, 异常的产生  运行时异常:程序运行中产生的异常:RuntimeException类.   编译时异常:程序在编译时产生的异常:除了RuntimeException类  其他都是编译时产生的 ...