注册组件
在父组件中使用子组件,首先必须注册子组件。
注册组件的作用的是,当我们在父组件的模板里写下组件名称
的标签,框架会从注册过的组件中查找匹配度最高的,简单来说就是,本地注册的优先级高于全局注册。
如果未注册组件,你希望框架从哪去加载组件呢?
假设我们注册了一个名为 Button
的组件,我们就可以在模板里创建自己的按钮了。
<div>
<Button />
</div>
传递数据
一个简单的 <Button />
显然不能满足需求,我们至少需要传入一个 text
和 onClick
吧,不然这个按钮没有任何意义。
父组件模板
<div>
<Button text="{{text}}" onClick="{{onClick}}" />
</div>
父组件数据
new Yox({
data: {
text: '确定',
onClick: function () {
alert('点我干毛!');
}
}
});
这里用插值语法设置了两个属性,它们会以对象的形式传给组件实例的 data
。
作为一个好的开发习惯,我们应该为子组件定义传入的数据格式。
为了方便别人看懂你的代码,请不要偷懒,自觉写好
propTypes
。
Button
组件
define(function () {
return {
// 外部数据格式,参考 组件 - 数据校验
propTypes: { },
// 内部数据定义
data: function () {
// this.get('text') 可以获取到外部传入的数据
return {
};
},
template: '<button on-click="click()">{{text}}</button>',
methods: {
click: function () {
this.get('onClick')();
}
}
}
});
数据流
父组件传给子组件的数据,理论上是只读的,请不要在子组件修改它。
你可以理解为子组件没有权限修改父组件传入的数据,这就是所谓的单向数据流。
事件流
子组件没有权限修改传入的数据,那么当我们需要修改数据时,有两种选择:
- 调用父组件传入的回调函数
- 子组件发射事件,父组件处理子组件的事件
我们比较推荐第二种,方便解耦。
父组件调用子组件
回调函数或事件,解决的是子组件通知父组件的机制。
有时候,父组件需要主动调用子组件,比如子组件是一个表单,我们希望获取表单的数据,那么表单组件可以定义一个 method
,如下:
methods: {
getData: function () {
return { };
}
}
在父组件的模板里,我们为表单组件设置一个引用名称,如下:
<Form ref="form" />
于是父组件就能通过以下方式获取表单组件的数据了。
this.$refs.form.getData();