# vita
**Repository Path**: oss360/vita
## Basic Information
- **Project Name**: vita
- **Description**: vita是一个js组件框架,主要约定了组件的生成方式和实例化方式,并提供了组件以及组件实例的生命周期管理。此外还提供了自动模块化封装,兼容seajs和requirejs,如果是UI相关组件,还可以封装成jquery插件以便通过jquery调用组件方法。
- **Primary Language**: JavaScript
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 1
- **Created**: 2019-08-02
- **Last Updated**: 2021-11-02
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# vita js组件框架 #
----------
## 简介 ##
vita是一个js组件框架,主要约定了组件的生成方式和实例化方式,并提供了组件以及组件实例的生命周期管理。此外还提供了自动模块化封装,兼容seajs和requirejs,如果是UI相关组件,还可以封装成jquery插件以便通过jquery调用组件方法。
## 基础能力 ##
1. `核心`:基础函数实现,核心能力不依赖第三方
2. `执行队列`:以生产和消费消息体的方式,实现js函数的执行队列,支持队列分类管理
3. `事件侦听`:以发布订阅的方式,实现在对象上的事件侦听,支持事件注册、监听、派发,事件派发处理使用了`执行队列`
4. `切面`:支持js对象和dom对象的事件/方法切面处理,支持事件前、事件后、事件前后处理
5. `ajax`:封装$.ajax以及$.fn.load方法,实现404、500等异常处理,实现统一遮罩等
6. `路由`:管理history(不是浏览器的history),可以判断是程序切换,还是前进后退按钮,并且可以限制路由变化
7. `组件框架`:js组件框架实现,组件可继承,并且维护组件及组件实例的生命周期,实现了js组件基类、js ui组件基类、js backbone组件基类、js biz业务组件基类
8. `模块`:js组件模块化封装,隐藏js组件的属性和私有函数(约定以“_”开头的为私有方法),支持与seajs和requirejs模块的相互调用
9. `jquery插件`:ui类组件,支持生成jquery插件,使用jquery来调用组件内公共方法
## 功能组件 ##
- 封装underscore工具,按使用对象拆解成`util`、`objectUtil`、`functionUtil`、`domUtil`、`collectionUtil`、`chain`、`arrayUtil`模块
- 封装bootstrap,按bootstrap组件分类解析成`input`、`container`、`inlineText`等等,支持主题切换
- datetime组件,主要用于移动端的时间选择
- dialog组件,对话框
- loading组件,遮罩
- popup组件,提示框,支持alert和confirm
- moveTo组件,移动动画,支持多段直接移动
- webAssist组件,路由规则配置化,将路由规则配置成约定的json数据即可实现单页面应用的界面切换
- htmlTag组件,自定义html标签(或者自定义class),目前实现两个能力,一个是将html里数据附加到指定dom的data($.fn.data)里,另一个是实现dom与model(主要是backbone的model)的数据双向绑定
## 目录结构 ##
vita由以下几个模块组成:
- `core`:核心组件,包括ajax、aop、debug(动态断点、调用栈输出)、event(事件侦听)、modular(模块化)、queue(执行队列)、router(路由)、widget(组件工厂)等
- `biz`:业务组件基类
- `modules`:功能组件,包括chart(chart图表的封装)、function(功能组件)、ui、util(工具类)等
- `themes`:下载的主题
- `demo`:封装bootstrap的组件demo
工程结构如下:
vita
--core
----core.js
----queue.js
----event.js
----aop.js
----ajax.js
----router.js
----modular.js
----debug.js
----widget.js
----widget.base.js
----widget.ui.js
--biz
----widget.biz.js
----widget.biz4b.js
--modules
----function
------datetime.js
------dialog.js
------htmlTag.js
------loading.js
------moveTo.js
------popup.js
------webAssist.js
----ui
------**.js(bootstrap组件封装)
----util
------**.js(underscore组件封装)
----chart
------**.js(chart图表封装)
--themes
------*/**.less(下载的bootstrap主题)
--demo(封装的bootstrap组件demo)
## 使用说明 ##
### (1)生成组件 ###
创建一个组件,一般需要三个入参,分别是widget_name,inherit,options,分别表示“组件名”,“需要继承的组件”,“组件参数”,格式如下:
vita.widget(widget_name,inherit,options);
> - `widget_name(组件名)`
> - 这是一个字符串,必填且唯一,是请求组件时的唯一索引。
> - 必须遵循js的变量命名规则。例如:”button”。
> - 允许带一个命名空间,比如:”ui.button”,此时框架会使用命名为”ui”的类,作为该组件的基类,而组件名仍为”button”。
> - `inherit(继承的组件)`
> - 可以是一个字符串,或者是一个字符串数组,例如”button”,或者[”button”]。
> - 必须是已有的组件名,如果没有找到指定组件,框架将忽略,这里指定的组件名,将按指定的顺序,作为该组件的基类。
> - 该入参为可选。
> - `options(组件参数)`
> - 必须是一个对象,为组件指定属性或者方法。
组件范例如下:
vita.widget("arrayUtil",{
inArray : function(){},
shift : function(){}
});
> 这是一个名为`arrayutil`的数组工具类,这个组件里提供了`inArray`和`shift`两个方法。
另一个范例:
vita.widget("myArray","arrayUtil",{
length : function(){}
});
> 这是一个名为`myarray`的组件,它继承了`arrayutil`组件,并提供了`length`方法,即,这个组件拥有`inArray`、`shift`和`length`三个方法。以上代码中`arrayUtil`也可以写成`["arrayUtil"]`。
再一个范例:
vita.widget("ui.button",{
_create : function(){
return $("");
},
_init : function(){
this.element.append("这是一个按钮");
}
});
> - 这是一个`button`组件,因为设置了`ui`这个命名空间,所以这个组件是继承自`ui`这个类(`ui`也是继承顶层的基类)。
> - `ui`组件必须实现`_create`方法,这个方法是用来创建dom对象或者jquery对象,并且需要返回这个对象。也可以创建对象的时候,就给这个对象设置各种属性,允许做二次变更的属性,不建议在这里赋值。
> - `_init`方法,是组件初始化方法,一般用来二次变更dom元素属性。建议允许变更的dom属性,在这个方法里设置。`this.element`所获取到的对象,就是`_create`方法所返回的对象,在所有的方法里都适用,因为`element`是`ui`类的一个属性。
> - 组件创建时,会先调用`_create`方法,再调用`_init`方法。在组件的生命周期中,`_create`方法只会被执行一次,而`_init`方法在组件创建时被调用后,每次使用jquery方法重置组件属性时,都还会被调用。
以上三个范例,除了所看到的方法外,它们都还拥有destroy(销毁)等基本方法。
#### 单例和多例 ####
组件在定义的时候,就必须在`options`里指定单例还是多例,不指定默认是单例。
单例模式
get singleton(){
return true;
}
或者
singleton : true
多例模式
get singleton(){
return false;
}
或者
singleton : false
一般建议,工具类组件使用单例,ui类组件使用多例。
> - 单例模式,通过`this.require`方法请求到的,就是一个模块实例,可以直接使用在组件里定义好的公用方法;
> - 多例模式,通过`this.require`方法请求到的,是一个仅拥有new方法的工厂,必须调用new方法,来生成实例,才能使用定义好的公用方法。
### (2)模块化 ###
组件生成后,会默认封装成模块,可以通过require方法请求得到。
### (3)显式的模块入口 ###
vita.modular.init({
index : "ui-example",
dependents : plugins,
callback : function(a){
$("body").append(a.getElement());
}
});
> - `vita.modular.init`是显式的模块入口,这个入口封装了seajs、requirejs的入口,会根据js的引用判断。如果没有引用seajs或者requirejs,则使用vita自己的模块化方式。
> - `index`指定第一个启动的模块,默认扩展名是js,可以不写;
> - `dependents`指定了依赖的js,如果要使用util库或者ui库,就要依赖util和ui的js,另外。`plugins`必须要引用,jquery也可以放在这里引用,但是必须要放在第一个。
> - `callback`是回调函数,入参是`index`指定模块的实例。即上例中的`a`,就是`example`这个模块实例化后的对象。
*备注:一般情况下不用这个入口。*
### (4)模块调用 ###
组件内,通过this.require方法进行请求,以下是单例组件的请求:
vita.widget("ui.button",{
_create : function(){
return $("");
},
_init : function(){
var array = this.require("arrayUtil");
var val = array.inArray("a",["a","b","c"]);
}
});
组件外,可以通过vita.widget.require请求。
var array = vita.widget.require("arrayUtil");
多例(ui)组件请求范例:
var button = this.require("button");
var b = button.new({id:"test",text:"测试"});
b.getElement().appendTo("body");
如果有使用jquery,还可以这样:
$(“#test”).button({text:"测试"});
> - 如果`#test`没有对应的组件实例,会给`#test`创建一个名为`button`的组件实例,其中`text`属性为`测试`
> - 如果`#test`存在对应的组件实例,则更新`text`属性为`测试`
接着还可以这样:
$(“#test”).button(“disable”,true);
> - 如果`#test`存在对应的名为`button`的组件实例,则会调用`button`组件的`disable`方法,入参为`true`
> - 该模式下,第一个参数是方法名(将屏蔽“_”开头的方法,因为约定为私有),后面的参数都是方法的入参,入参个数不限
### (5)执行队列 queue ###
生产消息:
vita.queues.produce(name, msg, handler, params);
> - `name`:队列名称
> - `msg`:消息体,可以是function
> - `handler`:如果`msg`是function,`handler`则是调用者,即function内的this
> - `params`:如果`msg`是function,`params`则是入参
消费消息(消费指定队列中下一个要被消费的消息):
vita.queues.consume(name);
> - `name`:队列名称
消费消息(消费指定队列中的所有消息):
vita.queues.consumeAll(name);
> - `name`:队列名称
### (6)事件侦听 event ###
增加侦听:
vita.event.addListener(widget,eventName,function);
> - `widget`:需要侦听事件的对象
> - `eventName`:事件名称
> - `function`:侦听到事件时促发的函数
> - 三个入参都是必须的
删除侦听:
vita.event.removeListener(widget,eventName,func);
> - `widget`:需要侦听事件的对象
> - `eventName`:事件名称
> - `function`:侦听到事件时促发的函数
> - 至少需要一个入参,可以仅删除指定对象的侦听,也可以按事件名称删除,也可以按函数删除,如`vita.event.removeListener(widget)`,或者`vita.event.removeListener(widget,eventName)`,或者`vita.event.removeListener(eventName)`等
事件触发:
vita.event.dispatchEvent(eventName, data);
> - `eventName`:事件名称
> - `data`:附加的数据
> - 针对ui组件,为了更精确的缩小范围,还有两种高级的方式,一是指定id,如`vita.event.dispatchEvent("#id1,id2", eventName, data)`;二是指定组件名,如`vita.event.dispatchEvent("vita.widgetName1 ,widgetName2" ,eventName, data)`。
### (7)js/dom切面 aop ###
在方法之前切入:
vita.aop.before(pointcut, advice, namespaces);
在方法之后切入:
vita.aop.after(pointcut, advice, namespaces);
在方法前后切入:
vita.aop.around(pointcut, advice, namespaces);
还原:
vita.aop.restore(pointcut, namespaces);
### (8)ajax ###
### (9)路由 router ###
### (10)动态断点 debug ###
动态断点,用来调试没有事先断点的地方:
vita.debug.debugger(pointcut, namespaces);
> - `pointcut`:需要debug的方法
> - `namespaces`:命名空间或者对象
> - 可以动态断点对象为全局函数、命名空间里的函数、组件实例的函数
动态输出调用栈:
vita.debug.trace(pointcut, namespaces)
> - `pointcut`:需要debug的方法
> - `namespaces`:命名空间或者对象
> - 可以动态输出调用栈的对象为全局函数、命名空间里的函数、组件实例的函数