该文档描述了组件的 API,在 San 主模块上暴露的 API 请参考文档 主模块API 。
初始化参数 data 解释
:
组件初始化数据。通常在组件反解 的场景下使用。
类型
: Object
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 var MyComponent = san.defineComponent ({});var myComponent = new MyComponent ({ el : document .getElementById ('my-label' ), data : { email : 'errorrik@gmail.com' , name : 'errorrik' } });
el 解释
:
组件根元素。传入此参数意味着不使用组件的 template 作为视图模板,组件视图由 San 自动反解。详情可参考组件反解 文档。
类型
: HTMLElement
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var MyComponent = san.defineComponent ({});var myComponent = new MyComponent ({ el : document .getElementById ('my-label' ), data : { email : 'errorrik@gmail.com' , name : 'errorrik' } });
owner 版本
:>= 3.7.0
类型
: Object
解释
:
指定组件所属的 owner 组件。指定 owner 组件后:
组件无需手工 dispose,owner dispose 时会自动释放
组件及其子组件 dispatch 的消息,owner 组件可以接收
更多说明请参考owner与parent 文档。
注意
:
指定 owner 后,不允许将组件 push 到 owner 的 children 中
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 san.defineComponent ({ mainClick : function ( ) { if (!this .layer ) { this .layer = new Layer ({ owner : this }); this .layer .attach (document .body ); } this .layer .show (); } });
source 版本
:>= 3.7.0
类型
: string|Object
解释
:
通过 HTML 格式的一个标签,声明组件与 owner 之间的数据绑定和事件。指定 source 同时需要指定 owner。更详细的用法请参考 手动创建子组件 文档,更多声明格式细节请参考 模板 与 事件 文档。
提醒
:
source 串的标签名称通常没什么用,除了以下情况:组件本身根节点为 template 时,以 source 的标签名称为准。
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 san.defineComponent ({ mainClick : function ( ) { if (!this .calendar ) { this .calendar = new Calendar ({ owner : this , source : '<x-cal value="{{birthday}}" on-change="birthdayChange($event)"/>' }); this .calendar .attach (document .body ); } }, birthdayChange : function (value ) { this .data .set ('birthday' , value); } });
transition 版本
:>= 3.6.0
类型
: Object
解释
:
组件的过渡动画控制器。可参考 动画控制器 和 动画控制器 Creator 文档。
用法
:
1 2 3 4 5 6 7 8 9 10 var MyComponent = san.defineComponent ({ template : '<span>transition</span>' }); var myComponent = new MyComponent ({ transition : { enter : function (el, done ) { }, leave : function (el, done ) { }, } });
生命周期钩子 生命周期代表组件的生存过程,在每个过程到达时将触发钩子函数。具体请参考生命周期 文档。
compiled 解释
:
组件视图模板编译完成。组件上的 compiled 方法将会被调用。
inited 解释
:
组件实例初始化完成。组件上的 inited 方法将会被调用。
created 解释
:
组件元素创建完成。组件上的 created 方法将会被调用。
attached 解释
:
组件已被附加到页面中。组件上的 attached 方法将会被调用。
detached 解释
:
组件从页面中移除。组件上的 detached 方法将会被调用。
disposed 解释
:
组件卸载完成。组件上的 disposed 方法将会被调用。
updated 解释
:
组件由于数据变化,视图完成一次刷新。组件上的 updated 方法将会被调用。
error 版本
:>= 3.10.7
解释
:
当捕获一个来自子孙组件的抛出异常时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含异常来源信息的字符串。此钩子捕获异常以后,不会再继续向父节点传递。
定义组件成员 template 解释
:
组件的视图模板。详细描述请参考视图模板 文档。
类型
: string
用法
:
1 2 3 san.defineComponent ({ template : '<span title="{{text}}">{{text}}</span>' });
filters 解释
:
声明组件视图模板中可以使用哪些过滤器。详细描述请参考过滤器 文档。
类型
: Object
用法
:
1 2 3 4 5 6 7 8 9 san.defineComponent ({ template : '<a>{{createTime | dateFormat("yyyy-MM-dd")}}</a>' , filters : { dateFormat : function (value, format ) { return moment (value).format (format); } } });
警告
:
filter 方法在运行时通过 this.data 可以触及组件的数据。但是,这么干会造成对数据的隐式依赖,导致数据变化时,视图不会随着更新。所以,filter 方法应该是无副作用的 pure function。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 var Bad = san.defineComponent ({ template : '<u>{{num | enhance}}</u>' , filters : { enhance : function (n ) { return n * this .data .get ('times' ); } }, initData : function ( ) { return { num : 2 , times : 3 }; } }); var Good = san.defineComponent ({ template : '<u>{{num | enhance(times)}}</u>' , filters : { enhance : function (n, times ) { return n * times; } }, initData : function ( ) { return { num : 2 , times : 3 }; } });
components 解释
:
声明组件中可以使用哪些类型的子组件。详细描述请参考components 文档。
类型
: Object
用法
:
1 2 3 4 5 6 var AddForm = san.defineComponent ({ components : { 'ui-timepicker' : TimePicker , 'ui-calendar' : Calendar } });
computed 解释
:
声明组件中的计算数据。详细描述请参考计算数据 文档。
类型
: Object
用法
:
1 2 3 4 5 6 7 8 9 10 san.defineComponent ({ template : '<a>{{name}}</a>' , computed : { name : function ( ) { return this .data .get ('firstName' ) + ' ' + this .data .get ('lastName' ); } } });
messages 解释
:
声明处理子组件派发消息的方法。详细描述请参考消息 文档。
类型
: Object
用法
:
1 2 3 4 5 6 7 8 9 10 11 var Select = san.defineComponent ({ template : '<ul><slot></slot></ul>' , messages : { 'UI:select-item-selected' : function (arg ) { var value = arg.value ; this .data .set ('value' , value); } } });
initData 解释
:
返回组件实例的初始数据。详细描述请参考初始数据 文档。
类型
: function():Object
用法
:
1 2 3 4 5 6 7 8 9 var MyApp = san.defineComponent ({ template : '<ul><li s-for="item in list">{{item}}</li></ul>' , initData : function ( ) { return { list : ['san' , 'er' , 'esui' , 'etpl' , 'esl' ] }; } });
trimWhitespace 定义组件模板解析时对空白字符的 trim 模式。
默认为 none ,不做任何事情
blank 时将清除空白文本节点
all 时将清除所有文本节点的前后空白字符
版本
:>= 3.2.5
类型
: string
用法
:
1 2 3 4 5 6 var MyApp = san.defineComponent ({ trimWhitespace : 'blank' });
delimiters 解释
:
定义组件模板解析时插值的分隔符。值为2个项的数组,分别为起始分隔符和结束分隔符。默认为:
版本
:>= 3.5.0
类型
: Array
用法
:
1 2 3 4 var MyComponent = san.defineComponent ({ delimiters : ['{%' , '%}' ], template : '<a><span title="Good {%name%}">Hello {%name%}</span></a>' });
transition 解释
:
定义组件根节点的过渡动画控制器。已废弃。
版本
:>= 3.3.0, < 3.6.0
类型
: Object
用法
:
1 2 3 4 5 6 7 var MyComponent = san.defineComponent ({ template : '<span>transition</span>' , transition : { enter : function (el ) { }, leave : function (el, done ) { }, } });
inheritAttrs 解释
:
属性透传 功能是否生效。默认值为 true 。当属性透传功能关闭时,id / class / style 的透传也将失效。
版本
:>= 3.14.1
类型
: boolean
用法
:
1 2 3 4 var MyComponent = san.defineComponent ({ inheritAttrs : false , template : '<span><slot/></span>' });
autoFillStyleAndId 解释
:
组件根节点是否应用外部通过绑定传入的 id / class / style。默认为 true 。
版本
:>= 3.7.5
类型
: boolean
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var AComponent = san.defineComponent ({ template : '<a class="inner">my component</a>' , autoFillStyleAndId : false }); var BComponent = san.defineComponent ({ template : '<b class="inner">my component</b>' }); var MyApp = san.defineComponent ({ component : { 'a-cmpt' : AComponent , 'b-cmpt' : BComponent }, template : '<div><a-cmpt class="outer"/><b-cmpt class="outer"/></div>' });
updateMode 解释
:
可控制视图刷新的逻辑,当前仅支持 optimized
。当取值为 optimized
时,对 s-for 指令的视图更新会根据不同浏览器环境进行优化,更新过程对 DOM 的操作和数据变化可能无法对应。
版本
:>= 3.7.4
类型
: string
用法
:
1 2 3 4 var MyComponent = san.defineComponent ({ updateMode : 'optimized' , template : '<ul><li s-for="item in list">{{item}}</li></ul>' });
aNode 解释
:
template
编译结果。包含该属性时,组件实例化时不会执行编译行为,可节省初始时间。通常用于组件预编译,开发时不直接编写,通过工具编译生成。ANode 处理可使用 san-anode-utils 。
类型
: Object
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 var MyComponent = san.defineComponent ({ aNode : { "directives" : {}, "props" : [ { "name" : "class" , "expr" : { "type" : 5 , "expr" : { "type" : 4 , "paths" : [ { "type" : 1 , "value" : "class" } ] }, "filters" : [ { "type" : 6 , "args" : [], "name" : { "type" : 4 , "paths" : [ { "type" : 1 , "value" : "_class" } ] } } ] } }, { "name" : "style" , "expr" : { "type" : 5 , "expr" : { "type" : 4 , "paths" : [ { "type" : 1 , "value" : "style" } ] }, "filters" : [ { "type" : 6 , "args" : [], "name" : { "type" : 4 , "paths" : [ { "type" : 1 , "value" : "_style" } ] } } ] } }, { "name" : "id" , "expr" : { "type" : 4 , "paths" : [ { "type" : 1 , "value" : "id" } ] } } ], "events" : [], "children" : [ { "textExpr" : { "type" : 7 , "segs" : [ { "type" : 1 , "value" : "Hello " }, { "type" : 5 , "expr" : { "type" : 4 , "paths" : [ { "type" : 1 , "value" : "name" } ] }, "filters" : [] } ] } } ], "tagName" : "p" } });
aPack 解释
:
aNode
的压缩结果。aPack
相比 aNode
在体积和传输上有较大优势,在解压性能上也比 template
解析要快很多。通常用于组件预编译,开发时不直接编写,通过工具编译生成。APack 处理可使用 san-anode-utils 。
版本
:>= 3.9.0
类型
: Array
用法
:
1 2 3 4 var MyComponent = san.defineComponent ({ aPack : [1 ,"p" ,4 ,2 ,"class" ,7 ,,6 ,1 ,3 ,"class" ,1 ,8 ,6 ,1 ,3 ,"_class" ,,2 ,"style" ,7 ,,6 ,1 ,3 ,"style" ,1 ,8 ,6 ,1 ,3 ,"_style" ,,2 ,"id" ,6 ,1 ,3 ,"id" ,,9 ,,2 ,3 ,"Hello " ,7 ,,6 ,1 ,3 ,"name" ,] });
组件方法 fire 描述
: fire({string}eventName, {*}eventArgument)
解释
:
派发一个自定义事件。San 为组件提供了自定义事件功能,组件开发者可以通过该方法派发事件。事件可以在视图模板中通过 on- 的方式绑定监听,也可以通过组件实例的 on 方法监听。可参考Event 文档。
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 var Label = san.defineComponent ({ template : '<template class="ui-label"><a on-click="clicker" title="{{text}}">{{text}}</a></template>' , clicker : function ( ) { this .fire ('customclick' , this .data .get ('text' ) + ' clicked' ); } }); var MyComponent = san.defineComponent ({ initData : function ( ) { return {name : 'San' }; }, components : { 'ui-label' : Label }, template : '<div><ui-label text="{{name}}" on-customclick="labelClicker($event)"></ui-label></div>' , labelClicker : function (doneMsg ) { alert (doneMsg); } });
on 描述
: on({string}eventName, {Function}eventListener)
解释
:
添加自定义事件监听器。 on 一般仅用在使用 JavaScript 动态创建的组件中,通过视图模板创建的子组件应通过 on- 的方式绑定监听。可参考动态子组件 文档
un 描述
: un({string}eventName, {Function=}eventListener)
解释
:
移除事件监听器。 当 eventListener 参数为空时,移除所有 eventName 事件的监听器。
dispatch 描述
: dispatch({string}name, {*}value)
解释
:
派发一个消息。消息将沿着组件树向上传递,直到遇到第一个处理该消息的组件。上层组件通过 messages 声明组件要处理的消息。消息主要用于组件与非 owner 的上层组件进行通信。可参考消息 文档。
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 var SelectItem = san.defineComponent ({ template : '<li on-click="select" class="{{value === selectValue ? \'selected\' : \'\'">' + '<slot></slot>' + '</li>' , select : function ( ) { var value = this .data .get ('value' ); this .dispatch ('UI:select-item-selected' , value); }, attached : function ( ) { this .dispatch ('UI:select-item-attached' ); }, detached : function ( ) { this .dispatch ('UI:select-item-detached' ); } }); var Select = san.defineComponent ({ template : '<ul><slot></slot></ul>' , messages : { 'UI:select-item-selected' : function (arg ) { var value = arg.value ; this .data .set ('value' , value); var len = this .items .length ; while (len--) { this .items [len].data .set ('selectValue' , value); } }, 'UI:select-item-attached' : function (arg ) { this .items .push (arg.target ); arg.target .data .set ('selectValue' , this .data .get ('value' )); }, 'UI:select-item-detached' : function (arg ) { var len = this .items .length ; while (len--) { if (this .items [len] === arg.target ) { this .items .splice (len, 1 ); } } } }, inited : function ( ) { this .items = []; } }); var MyComponent = san.defineComponent ({ components : { 'ui-select' : Select , 'ui-selectitem' : SelectItem }, template : '' + '<div>' + ' <ui-select value="{=value=}">' + ' <ui-selectitem value="1">one</ui-selectitem>' + ' <ui-selectitem value="2">two</ui-selectitem>' + ' <ui-selectitem value="3">three</ui-selectitem>' + ' </ui-select>' + '</div>' });
watch 描述
: watch({string}dataName, {function({*}value)}listener)
解释
:
监听组件的数据变化。通常我们使用绑定,在子组件数据变化时自动更新父组件的对应数据。 watch 一般仅用在使用 JavaScript 动态创建的组件中。可参考动态子组件 文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 san.defineComponent ({ initLayer : function ( ) { if (!this .monthView ) { var monthView = new MonthView (); this .monthView = monthView; this .monthView .watch ('value' , (function (value ) { this .data .set ('value' , value); }).bind (this )); this .watch ('value' , function (value ) { monthView.data .set ('value' , value); }); this .monthView .attach (document .body ); } } });
ref 描述
: ref({string}name)
解释
:
获取定义了 s-ref 的子组件或 HTMLElement。详细请参考组件层级 文档。
注意
:组件根元素即使定义了 s-ref ,也无法通过 ref 方法获得。获取组件根元素请使用 this.el 。
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 var AddForm = san.defineComponent ({ components : { 'ui-timepicker' : require ('../ui/TimePicker' ), 'ui-calendar' : require ('../ui/Calendar' ) }, submit : function ( ) { this .ref ('endDate' ); this .ref ('endHour' ); this .ref ('rootNode' ); this .el ; } });
slot 版本
:>= 3.3.0
描述
: {Array} slot({string=}name)
解释
:
获取组件插槽的节点信息。返回值是一个数组,数组中的项是节点对象。通常只有一项,当 slot 声明中应用了 if 或 for 时可能为 0 项或多项。节点对象包含 isScoped 、 isInserted 和 children。
插槽详细用法请参考 slot 文档。
注意
:不要对返回的 slot 对象进行任何修改。如果希望操作视图变更,请操作数据。
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 var Panel = san.defineComponent ({ template : '<div><slot s-if="!hidden"/></div>' , }); var MyComponent = san.defineComponent ({ components : { 'x-panel' : Panel }, template : '' + '<div>' + '<x-panel hidden="{{folderHidden}}" s-ref="panel"><p>{{desc}}</p></x-panel>' + '</div>' , attached : function ( ) { this .ref ('panel' ).slot ().length var contentSlot = this .ref ('panel' ).slot ()[0 ]; contentSlot.isInserted contentSlot.isScoped } }); var myComponent = new MyComponent ({ data : { desc : 'MVVM component framework' , } });
nextTick 解释
:
San 的视图更新是异步的。组件数据变更后,将在下一个时钟周期更新视图。如果你修改了某些数据,想要在 DOM 更新后做某些事情,则需要使用 nextTick
方法。
用法
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 const Component = san.defineComponent ({ template : ` <div> <div s-ref="name">{{name}}</div> <button on-click="clicker">change name</button> </div> ` , initData ( ) { return {name : 'erik' }; }, clicker ( ) { this .data .set ('name' , 'leeight' ); console .log (this .ref ('name' ).innerHTML ); this .nextTick (() => { console .log (this .ref ('name' ).innerHTML ); }); } });