组件通讯
通讯概览
这一节主要是解释上面这张图。
Omi框架组建间的通讯非常便利灵活,足够满足业务场景需要。因为有许多可选方案进行通讯:
- on-* 代表传递父组件向子组件注入的回调函数,比on-page-change="pageChangeHandler"
- data-* 代表直接传递字符串
- :data-* 代表传递javascript表达式,比如data-num="1" 代表传递数字1而非字符串,data-num="1+1"可以传递2。
- ::data-* 代表传递父组件的属性,比如上面的::data-items="data.items"就代表传递this.data.items给子组件
- data 代表传递父组件的属性,比如data="user"代表传递this.user给子组件
- :data 代表传递javascript表达式,比如data="{ name : 'dntzhang' , age : 18 }"代表传递{ name : 'dntzhang' , age : 18 }给子组件
- group-data 代表传递父组件的数组一一映射到子组件
子与父通讯
通过on-*传递回调函数给子组件,子组件就可以执行注入的父组件中的方法,如;
... handlePageChange () { } render () { return `<div> <h1>Pagination Example</h1> <content name="content" ></content> <pagination name="pagination" :data-total="100" :data-page-size="10" :data-num-edge="1" :data-num-display="4" on-page-change="handlePageChange" ></pagination> </div>`; }
- 可以看到上面使用了pagination组件。里面声明了on-page-change来指向this.handlePageChange
- 在pagination组件内部可以通过this.data.onPageChange 来执行this.handlePageChange方法
data-*通讯
class Hello extends Omi.Component { constructor(data) { super(data); } render() { return ` <div> <h1 onclick="handleClick(this, event)">Hello ,{{name}}!</h1> </div> `; } } Omi.tag('hello', Hello); class App extends Omi.Component { render() { return ` <div> <hello data-name="Omi" ></hello> </div> `; } } Omi.render(new App(),"#container");
一般data-*用来传递值类型,如string、number。值得注意的是,通过data-*接收到的数据类型都是string,需要自行转成number类型,或者使用:data-*来传递number。
:data-*通讯
- :data-* 代表传递javascript表达式,比如data-num="1" 代表传递数字1而非字符串,data-num="1+1"可以传递2。
::data-*通讯
- ::data-* 代表传递父组件的属性,比如上面的::data-items="data.items"就代表传递this.data.items给子组件
data通讯
如上面代码所示,通过 data-name="Omi"可以把name传递给子组件。下面的代码也可以达到同样的效果。
... class App extends Omi.Component { constructor(data) { super(data); this.helloData = { name : 'Omi' }; } render() { return ` <div> <hello data="helloData" ></hello> </div> `; } } Omi.render(new App(),"#container");
使用data声明,会去组件的instance(也就是this)下找对应的属性,this下可以挂载任意复杂的对象。所以这也就突破了data-*的局限性。
如果instance下面的某个属性下面的某个属性下面的某个数组的第一个元素的某个属性要作为data传递Hello怎么办? 没关系,data声明是支持复杂类型的,使用方式如下:
... class App extends Omi.Component { constructor(data) { super(data); this.complexData ={ a:{ b:{ c:[ { e:[{ name:'ComplexData Support1' },{ name:'ComplexData Support2' }] }, { name: 'ComplexData Support3' } ] } } }; } render() { return ` <div> <hello data="complexData.a.b.c[1]" ></hello> </div> `; } } ...
group-data通讯
group-data专门是为了给一组组件批量传递data而设计。
import Hello from './hello.js'; Omi.makeHTML('Hello', Hello); class App extends Omi.Component { constructor(data) { super(data); this.testData = [{name: 'Omi'}, {name: 'dntzhang'}, {name: 'AlloyTeam'}]; } render() { return ` <div> <hello group-data="testData" ></hello> <hello group-data="testData" ></hello> <hello group-data="testData" ></hello> </div> `; } } Omi.render(new App(),"#container");
只需要在声明的子组件上标记group-data,就会去当前组件的instance(也就是this)下面找对应的属性,然后根据当前的位置,和对应数组的位置会一一对应起来。
运行结果如下:
同样group-data支持复杂数据类型的映射,需要注意的是,group-data映射的终点必须是一个数组:
import Hello from './hello.js'; Omi.tag('hello', Hello); class App extends Omi.Component { constructor(data) { super(data); this.complexData ={ a:{ b:{ c:[ { e:[{ name:'ComplexData Support1' },{ name:'ComplexData Support2' }] }, { name: 'ComplexData Support3' } ] } } }; } render() { return ` <div> <hello group-data="complexData.a.b.c[0].e" ></hello> <hello group-data="complexData.a.b.c[0].e" ></hello> </div> `; } } Omi.render(new App(),"#container");
标记name
... class App extends Omi.Component { constructor(data) { super(data); } installed(){ this.hello.data.name = "Omi"; this.update() } render() { return ` <div> <hello name="hello" ></hello> </div> `; } } Omi.render(new App(),"#container");
标记omi-id
... class App extends Omi.Component { constructor(data) { super(data); } installed(){ Omi.get("hello").data.name = "Omi"; this.update() } render() { return ` <div> <hello omi-id="hello" ></hello> </div> `; } } Omi.render(new App(),"#container");
通过在组件上声明omi-id,标记omi-id是全局注册,在程序任何地方可以通过Omi.get拿到该对象的实例。