Omi教程-组件通信攻略大全

组件通信

Omi框架组建间的通信很是遍历灵活,由于有许多可选方案进行通信:html

  • 经过在组件上声明 data-* 传递给子节点
  • 经过在组件上声明 data 传递给子节点 (支持复杂数据类型的映射)
  • 父容器设置 childrenData 自动传递给子节点
  • 声明 group-data 传递(支持复杂数据类型的映射)
  • 彻底面向对象,能够很是容易地拿到对象的实例,以后能够设置实例属性和调用实例的方法

因此通信变得畅通无阻,下面一一来举例说明。git

data-*通信

class Hello extends Omi.Component {
    constructor(data) {
      super(data);
    }
    style () {
      return  `
      h1{
        cursor:pointer;
      }
      `;
    }
    handleClick(target, evt){
      alert(target.innerHTML);
    }
    render() {
      return  `
      <div>
        <h1 onclick="handleClick(this, event)">Hello ,{{name}}!</h1>
      </div>
        `;

    }
}

Omi.makeHTML('Hello', Hello);

class App extends Omi.Component {
    constructor(data) {
        super(data);
    }
  
    render() {
        return  `
        <div>
            <Hello data-name="Omi" />
        </div>
        `;
    }
}

Omi.render(new App(),"#container");

通常data-用来传递值类型,如string、number。值得注意的是,经过data-接收到的数据类型都是string,须要自行转成number类型。
一般状况下,data-能知足咱们的要求,可是遇到复杂的数据类型是没有办法经过大量data-去表达,因此能够经过data通信,请往下看。github

data通信

如上面代码所示,经过 data-name="Omi"能够把name传递给子组件。下面的代码也能够达到一样的效果。web

...
class App extends Omi.Component {
    constructor(data) {
      super(data);
      this.helloData = { name : 'Omi' };
    }
  
    render() {
        return  `
        <div>
            <Hello data="helloData" />
        </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]" />
        </div>
        `;
    }
}
...

点击这里→data映射复杂数据组件化

childrenData通信

...
class App extends Omi.Component {
    constructor(data) {
      super(data);
      this.childrenData = [{ name : 'Omi' } , { name : 'dntzhang' }];
    }
  
    render() {
        return  `
        <div>
            <Hello  />
            <Hello  />
        </div>
        `;
    }
}

Omi.render(new App(),"#container");

通用this.childrenData传递data给子组件,childrenData是一个数组类型,因此支持同时给多个组件传递data,与render里面的组件会一一对应上。this

group-data通信

childrenData的方式能够批量传递数据给组件,可是有不少场景下data的来源不必定非要都从childrenData来,childrenData是个数组,会和组件的顺序一一对应,这就给不一样传递方式的data必须所有集中的childrenData中,很是不方便。group-data专门为解决上面的痛点而生,专门是为了给一组组件批量传递data。code

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 group-data="testData" />
            <Hello group-data="testData" />
        </div>
        `;

    }
}

Omi.render(new App(),"#container");

只须要在声明的子组件上标记group-data,就会去当前组件的instance(也就是this)下面找对应的属性,而后根据当前的位置,和对应数组的位置会一一对应起来。htm

运行结果以下:

点击这里→group-data

一样group-data支持复杂数据类型的映射,须要注意的是,group-data映射的终点必须是一个数组:

import Hello from './hello.js';


Omi.makeHTML('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 group-data="complexData.a.b.c[0].e" />
        </div>
        `;

    }
}

Omi.render(new App(),"#container");

点击这里→group-data映射复杂数据

经过对象实例

...
class App extends Omi.Component {
    constructor(data) {
        super(data);
    }
    
    installed(){
        this.hello.data.name = "Omi";
        this.update()
    }
  
    render() {
        return  `
        <div>
            <Hello name="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" />
        </div>
        `;

    }
}

Omi.render(new App(),"#container");

经过在组件上声明omi-id,在程序任何地方拿到该对象的实例。这个能够算是跨任意组件通信神器。

特别强调

  • 经过childrenData或者data方式通信都是一锤子买卖。后续变动只能经过组件实例下的data属性去更新组件
  • 经过data-✼通信也是一锤子买卖。后续变动只能经过组件实例下的data属性去更新组件。
  • 关于data-✼通信也能够不是一锤子买卖,可是要设置组件实例的dataFirst为false,这样的话data-✼就会覆盖组件实例的data对应的属性

关于上面的第三条也就是这样的逻辑伪代码:

if(this.dataFirst){
    this.data = Object.assign({},data-✼ ,this.data);
}else{
    this.data = Object.assign({},this.data, data-✼);
}

招募计划

相关文章
相关标签/搜索