Aitter's Blog

组件编写规范

组件的封装有利用于代码的复用,封装统一的数据处理逻辑,对外提供接口,灵活配置与扩展,调用方便,利于维护。

原则

  • 开闭原则:对内修改关闭,对外扩展开放
  • 单例模式:同一个组件,在多次调用时,只使用一个单例

闭包

使用闭包:减少全局变量的污染,避免与其它插件冲突

严格模式 (strict mode)

使用严格模式:添加 use strict 标识

  • 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
  • 消除代码运行的一些不安全之处,保证代码运行的安全;
  • 提高编译器效率,增加运行速度;
  • 为未来新版本的Javascript做好铺垫。

组件说明

组件应添加组件说明,包含:组件名称、作者、版本、依赖项、使用方式、源码地址

/**
* module: Button
* author: XXX
* version: v0.0.1
* use age: ....
* deps: [...]
* github: ...
**/

构造函数

组件的状态和属性都应该在构造函数中进行初始化

插件定义

通用插件定义

  • 在内部返回每一个jQuery对象,插件的实例缓存到jQ对象的data
  • 要的参数的类型调用组件不同的方法
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('qk.button')
if (!data) $this.data('qk.button', (data = new Button(this)))
if (typeof option == 'string') data[option].call($this)
})
}

事件的命名空间

在开发较复杂的组件时,应添加事件命名空间,方便事件的管理,参见bootstrap modal组件

对外开放配置

组件通常有很多的配置,将配置接口对外开放,可方便用户对组件进行详情的配置与自定义

$.bn.button.defaults={ ... }

注意: 组件内部使用到的模板、class、id等都应该放到配置中,以便使用者自定义

对外开放构造器

将构造器对外开放,可方便外部对插件进行扩展升级

$.fn.button.Constructor = Button;

解决与其它重名插件的冲突

为防止组件名称与其它组件重名,应对外提供onConflict接口进行重命名。

var old = $.fn.button;
$.fn.button.noConflict = function () {$.fn.button = old;return this;}

生命周期

组件的生命周期包含:组件状态初始化、数据初始化、事件绑定、更新、销毁

结构

  • PUBLIC CLASS DEFINITION:类定义,定义了插件构造方法类及方法。
  • PLUGIN DEFINITION:插件定义,上面只是定义了插件的类,这里才是实现插件的地方。
  • PLUGIN NOCONFLICT:插件命名冲突解决
  • DATA-API:DATA-属性接口

模板

/**
* module: Button
* author: XXX
* version: v0.0.1
* use age: ....
* deps: [...]
* github: ...
**/
!function ($) {
"use strict";
// CLASS DEFINITION
// ================
var Button = function (element, options) {/*some code*}
Button.VERSION='v1.0.1';
Button.prototype.setState = function (state) {/*some code*/}
Button.prototype.toggle = function () {/*some code*/}
// PLUGIN DEFINITION
// =================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('qk.button')
if (!data) $this.data('qk.button', (data = new Button(this)))
if (typeof option == 'string') data[option].call($this)
})
}
var old = $.fn.button;
$.fn.button = Plugin;
$.fn.button.Constructor = Button;
$.fn.button.defaults = {loadingText: 'loading...'}
// NO CONFLICT
// ===========
$.fn.button.noConflict = function () {
$.fn.button = old;
return this;
}
// DATA-API
// ========
$(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {/*some code*/})
}(jQuery, window, undefined);