组件双向绑定
组件的v-model
指令是如下语法的语法糖:
<Component v-model="propName" />
=>
<Component
value={self.get('propName')}
ev-$change:value={function(c, value) {
self.set('propName', value);
}}
/>
所以只要组件接受value
属性,并且当value
改变时,触发$change:value
事件,就可以给该组件使用v-model
指令进行数据的双向绑定。事实上:组件只需要支持value
属性即可,而$change:value
事件是组件的默认事件,无需显式触发。
<button ev-click={self.add}>+1</button>
var Component = Intact.extend({
template: template,
defaults: function() {
return {value: 0};
},
add: function() {
this.set('value', this.get('value') + 1);
}
});
var Component = self.Component;
<div>
<Component v-model="count" />
count属性值为:{self.get('count')}
</div>
Intact.extend({
template: template,
defaults: function() {
return {count: 0};
},
_init: function() {
this.Component = Component;
}
});
甚至我们可以在子组件初始化,而父组件没有定义绑定的属性时,强制初始化父组件的属性值。要达到这个目的,只需要在组件的_init()
生命周期函数中,触发$change:value
即可。
<button ev-click={self.add}>+1</button>
var Component = Intact.extend({
template: template,
defaults: function() {
return {value: 0};
},
_init: function() {
// 组件初始化时,如果父组件传入的绑定属性值为undefined
// 则立即设置为默认值0,让其触发$change:value事件
if (this.get('value') === undefined) {
this.set('value', 0);
}
},
add: function() {
this.set('value', this.get('value') + 1);
}
});
var Component = self.Component;
<div>
<Component v-model="count" />
count属性值为:{self.get('count')}
</div>
Intact.extend({
template: template,
_init: function() {
this.Component = Component;
}
});
通过上例可以看到,即使使用组件Component
时,绑定的属性未定义,依然能将count
初始化为0。这在使用组件操作表单时,能提供便利性,你无需为每一个元素初始化属性值。当然在v2.2.0
版本中,我们还以通过$receive
事件,在组件更新再次接收到undefined
值时,将它设为0
由于
v-model
被编译成了ev-$change:value
,所以我们不能再次添加该属性,如果你需要确实需要在属性变更后,执行某个方法,可以在组件中通过on
监听绑定的属性变更事件,或者大多数情况下,我们也可以通过$changed:value
事件达到类似的目的。