组件
Omi框架完全基于组件体系设计,我们希望开发者可以像搭积木一样制作Web程序,一切皆是组件,组件也可以嵌套子组件形成新的组件,新的组件又可以当作子组件嵌套至任意组件形成新的组件...
上面的Hello Omi的例子已经说明了组件大概,这里再使用Todo的例子来讲解Omi组件体系的使用。
先定义一个List组件用来展示列表:
class List extends Omi.Component { render () { return `<ul> <li o-repeat="item in items">{{item.text}}</li> </ul>`; } }
使用o-repeat="item in items"来遍历传入的items,当然也可以拿到item的索引,通过{{$index}}就可以:
<li o-repeat="item in items">{{$index}} - {{item}}</li>
怎么使用这个List?我们需要使用Omi.tag把List制作成可以声明式的标签,在render方法中就能直接使用该标签。如下所示:
import List from './list.js'; Omi.tag('list', List); class Todo extends Omi.Component { constructor(data) { super(data) } add (evt) { evt.preventDefault(); this.data.items.push({text: this.data.text}) this.data.text = '' this.update() } style () { return ` h3 { color:red; } button{ color:green;} `; } handleChange(target){ this.data.text = target.value; } render () { return `<div> <h3>TODO</h3> <list ::data-items="data.items" ></list> <form onsubmit="add(event)" > <input type="text" onchange="handleChange(this)" value="{{text}}" /> <button>Add #${this.data.items.length}</button> </form> </div>`; } } Omi.render(new Todo({ items: [] ,text : '' }),"body");
注意看上面的这行代码<list ::data-items="data.items" ></list>。这样就把父组件的data.items传递给了子组件的data.items。这里解释下没有冒号,一个冒号和两个冒号:
data-* 代表直接传递字符串
:data-* 代表传递javascript表达式,比如data-num="1" 代表传递数字1而非字符串,data-num="1+1"可以传递2。
::data-* 代表传递父组件的属性,比如上面的::data-items="data.items"就代表传递this.data.items给子组件
多个中划线会形成驼峰在子组件中访问。比如 data-page-index 在子组件中使用 this.data.pageIndex 访问。
这里需要特别强调的是,为了更加的自由和灵活度。Omi没有内置数据变更的自动更新,需要开发者自己调用update方法。 关于Omi组件通讯其实有4种方案,这个后续教程会专门来讲。