定义组件
properties
定义组件原型链属性和方法
上例中定义的组件,并不能直接使用,因为没有个template
的组件不能实例化,它更像一个抽象类,
可供其他组件继承。
以继承父组件的方式定义组件:
var SubComponent = Component.extend({
template: '<div>sub-component</div>'
});
组件有个关键属性defaults
,它用来定义组件的默认数据。在组件实例化时,会和传入组件的属性
进行合并Object.assign()
赋给组件实例的props
属性,作为组件的最终数据。
defaults
支持两种取值类型:Object & Function
。
@deprecated
var Component;
Component = Intact.extend({
template: '<div>a = {self.get("a")}</div>',
defaults: {
a: 1
}
});
如果以Object
类型定义defaults,在组件继承时,会自动合并。
var SubComponent;
SubComponent = Component.extend({
template: '<div>a = {self.get("a")}<br />b = {self.get("b")}</div>',
defaults: {
b: 2
}
});
可以看到,SubComponent
组件并没有定义a
属性,但是在模板中却取到了a
,这是因为继承Component
时,
也继承了它的默认数据。
这种方式在定义组件时非常方便,但如果使用不当,会存在以下问题。
var Component = Intact.extend({
template: '<div>\
<button ev-click={self.add}>+1</button>\
a.a = {self.get("a.a")}\
</div>',
defaults: {
},
add: function() {
this.set('a.a', this.get('a.a') + 1);
});
Intact.extend({
template: template,
_init: function() {
this.Component = Component;
}
});
其实这一切的根源是由于Intact合并数据时,使用的Object.assign()
,而这只是一个浅拷贝函数,对于深层嵌套的引用类型,
仍然拷贝的是引用。在组件继承时,也存在同样的问题。
所以在你的数据存在引用嵌套时,我们应该使用Function
定义defaults
,它每次都会返回一份新数据。
Function
类型
使用Function
定义defaults
,应该返回一个Object
。
var Component = Intact.extend({
template: '<div>\
<button ev-click={self.add}>+1</button>\
a.a = {self.get("a.a")}\
</div>',
defaults: function() {
return {
a: {a: 1}
};
},
add: function() {
this.set('a.a', this.get('a.a') + 1);
}
});
var Component = self.Component;
<div>
<Component />
<Component />
</div>
Intact.extend({
template: template,
_init: function() {
}
});
此时,每个组件的数据是独立的了。
@since v2.3.0
组件会在初始化和更新时验证属性合法性,我们只需要通过组件的静态属性propTypes
定义数据验证方式即可。
当组件验证失败时,会在打印错误信息,但不会终端程序运行。数据的验证只会在开发环境进行。
- String
- Number
- Boolean
- Array
- Object
- Function
- Date
- RegExp
对于自定义构造函数,使用instanceof
进行检测,例如Intact.VNode
用于检测是否时虚拟dom对象vnode
Component.propTypes = {
vnode: Intact.VNode
};
枚举类型
通过数组可以指定枚举类型的数据,甚至可以和构造函数搭配使用,它们之间时”或“的关系
Component.propTypes = {
enum: ['left', 'bottom', 'right', 'top'],
enumWithObject: ['left', 'bottom', 'right', 'top', Object],
}
对于复杂的验证方法我们可以指定validator
函数进行验证,该函数返回布尔值true
则验证通过,false
则验证失败,或者返回字符串来作为错误提示信息。
Component.propTypes = {
value: {
validator: function(value) {
if (value > 100 || value < 0) {
return "the value must be between 0 and 100";
}
return true;
}
}
}
必填属性
添加required: true
即可指定该属性为必填项
Component.propTypes = {
value: {
type: Number,
required: true
}
}
使用ES6/7
Class
的static
语法,可以如下定义
另一个组件的重要属性便是template
,它用来定义组件的模板。它既可以传入模板字符串,
又可以传入模板函数,如果传入模板字符串,会调用Intact.Vdt.compile()
方法将之编译成模板函数。
模板语法请参考章节。
Intact.extend({
});