KISSY 中, 通过 add( name, fn ) 方法来添加新的模块. 在 KISSY 内部, 代码也是这么组织的.
下面通过个小例子来说明如何开发自定义组件.
在动手写 KISSY 组件之前, 还需要了解一下 KISSY 组件的开发流程相信会对你有用的.
在开发过程中, 开发者(就拿我来举例吧), 经常会出现:
我们需要避免这些问题(需求不明确, 盲目动手, 代码冗长, 写了后面的忘了前面的逻辑, 导致可扩展性差, 可复用性也差). HOW?
以前听人提过 Literate Programming(文学化编程) [1] 一词, 说的是:
Literate Programming
文学编程自由地表达逻辑, 而且它用人类日常使用的语言写出来, 就好像一篇文章一样, 让开发者用他们自己思维内在的逻辑和流程所要求的顺序开发程序.
现在越来越觉得, 其实, 写代码和写文章一样, 一个代码完成, 给别人阅读, 就得像看书一样, 从头至尾地, 能清晰的让阅读的人知道这代码实现的功能是什么, 适合/不适合哪些情况, 在使用时有哪些需要注意的地方;
在实际开发中, 除了给代码加注释外, 还有很多代码不能做的事情, 需要更多的文档来支持开发, 下面拿 ImageZoom slide [2] 为例说明一下:
总体流程, 如下所示:
一个需求到来, 比如这个图片放大效果, 首先我们需要这个功能能用在哪些地方, 或哪些网站上已经使用了, 如果有的话, 就对比一下不同的情况下不同的要求, 如 #slide4 . 这样以后, 对比自己的需求, 想好要实现什么功能, 哪些功能保留, 哪些功能不需要, —- 明确需求;
需求明确之后, 查找现有的同类组件, 看看他们针对这个问题, 是怎么实现的, 实现哪些功能, 哪些可以借鉴的地方, 哪些不足的地方要避免或者改进, 如 #slide6 , —- 明确要实现的功能有哪些;
分离出完成整个功能需要的几个核心功能点, 并针对各个功能点逐个描述, 如 #slide8 , 这也可以帮你理清思路, —- 进一步明确待实现功能;
针对上述的几个功能点, 分别给出实现方案, 或者其他的技术难点, 又或者是算法上的分析等, 如 #slide9 , — 明确如何实现;
设计好的公共 API , 并在此说明, 也可以根据使用场景, 给出一些范例来说明 API 的使用, 如 #slide14 , 这里可以在开始时设计的尽量精简些, —- 明确 API 接口;
简略或者详细的制定一个开发计划, 及发布的版本和时间等, —- 明确进度;
可选的部分, 用于记录所有开发过程中碰到的杂类问题或者和其他同学的讨论.
我们建议每个 KISSY 组件下, 都存放一个 slide.html, 其内容包含上述几部分内容. 这个 slide 随着你的开发过程的推进, 也会不断添加更新, 最后发布时连同组件源代码一起, 形成非常好的知识体系, 这样, 给别人或是几十年后的自己阅读, 也会像看文章一样的有条理.
关于代码组织, [4] 和 KISSY 工程 README 中都有些简单介绍, 下面简单说明下推荐的目录结构:
- widget-name
assets: 存放 css, img 等相关文件
build.properties/build.xml: 打包配置文件
widget-name.js: 组件核心代码
slide.html: 上面所说的调研文档
test.html: 测试文件
- tests: 测试用例目录
- widget-name-spec.js: 测试用例脚本文件, 可以有多个, 但务必以-spec为后缀
- 内部代码组织:采用 module, sub module 来分拆和组织代码
- 外部调用接口:component 形式,包括工具型组件 utils 和 UI 型组件 widgets
原则:尽量避免潜在冲突,同时力求精简短小和见名知意。
全局变量: g_ks_comp_xxx 比如: g_ks_suggest_callback
class/id 命名: ks-comp[-xxx] 比如: ks-editor-toolbar-item
data 属性命名: data-ks-comp[-xxx] 比如: data-ks-suggest
hook 规范: KS_Comp 比如: KS_Switchable
- config 属性:
- 以小驼峰形式, 比如 minDate;
- 常用 config 属性, 如trigger, container, containerCls, triggerType, type, 固定名字, 所有组件保持一致;
- config 的属性值, 对于位置, 用数组形式, 比如 offset: [10, 20];
注意: 为了避免太冗长, 在保持清晰和无潜在冲突的情况下, 可以打破原则, 比如:
<div class="KS_Widget" data-widget-type="Tabs" data-widget-config="{...}">
罗罗嗦嗦这么一大堆后, 不知道你是否觉得简单? 非常推荐基于 KISSY 尝试去实现一个组件, 一切都很简单的^o^
注意: 上面的 StarScore 组件仅是示范,实际应用中,还更复杂些,这个组件将会在 KISSY 1.2 时正式发布.