组件

Omi框架完全基于组件体系设计,我们希望开发者可以像搭积木一样制作Web程序,一切皆是组件,组件也可以嵌套子组件形成新的组件,新的组件又可以当作子组件嵌套至任意组件形成新的组件...

简单组件

这里使用Todo的例子来讲解Omi组件体系的使用。

class Todo extends Omi.Component {
constructor(data) {
super(data);
}
add (evt) {
evt.preventDefault();
this.data.items.push(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>
<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>
<form onsubmit="add(event)" >
<input type="text" onchange="handleChange(this)" value="{{text}}" />
<button>Add #{{items.length}}</button>
</form>
</div>`;
}
} Omi.render(new Todo({ items: [] ,text : '' }),"body");

组件生成的HTML最终会插入到body中。上面的例子展示了Omi的部分特性:

  • data传递: new Todo(data,..)的data可以直接提供给render方法里的模板
  • 局部CSS: h3只对render里的h3生效,不会污染外面的h3;button也是同样的
  • 声明式事件绑定: onchange调用的就是组件内的handleChange,this可以拿到当然的DOM元素,还可以拿到当前的event
  • 需要手动调用update方法才能更新组件

这里需要特别强调的是,为了更加的自由和灵活度。Omi没有内置数据变更的自动更新,需要开发者自己调用update方法。

你也可以和oba或者mobx一起使用来实现自动更新。

[点击这里->在线试试]

组件嵌套

如果页面超级简单的话,可以没有组件嵌套。但是绝大部分Web网页或者Web应用,需要嵌套定义的组件来完成所有的功能和展示。比如上面的Todo,我们也是可以抽取出List。

这样让程序易维护、可扩展、方便复用。如,我们抽取出List:

class List extends Omi.Component {
constructor(data) {
super(data);
} render () {
return `<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>`;
}
}

怎么使用这个List?我们需要使用Omi.makeHTML把List制作成可以声明式的标签,在render方法中就能直接使用该标签。如下所示:

import List from './list.js';

Omi.makeHTML('List', List);

class Todo extends Omi.Component {
constructor(data) {
super(data);
this.data.length = this.data.items.length;
this.listData = { items : this.data.items };
} add (evt) {
evt.preventDefault();
this.list.data.items.push(this.data.text);
this.data.length = this.list.data.items.length;
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 name="list" data="listData" />
<form onsubmit="add(event)" >
<input type="text" onchange="handleChange(this)" value="{{text}}" />
<button>Add #{{length}}</button>
</form>
</div>`;
}
}
  • 第3行,通过makeHTML方法把组件制作成可以在render中使用的标签。当然Omi.makeHTML('List', List);也可以写在List组件的代码下面。
  • 第34行,在父组件上定义listData属性用来传递给子组件。
  • 第34行,在render方法中使用List组件。其中name方法可以让你在代码里通过this快速方法到该组件的实例。data="listData"可以让你把this.listData传递给子组件。

需要注意的是,父组件的this.listData会被通过Object.assign浅拷贝到子组件。

这样做的目的主要是希望以后DOM的变更都尽量修改子组件自身的data,然后再调用其update方法,而不是去更改父组件的listData。

关于Omi组件通讯其实有4种方案,这个后续教程会专门来讲。

点击这里→在线试试

招募计划

Omi教程-组件的更多相关文章

  1. Omi教程-组件通讯

    组件通讯 Omi框架组建间的通讯非常遍历灵活,因为有许多可选方案进行通讯: 通过在组件上声明 data-* 传递给子节点 通过在组件上声明 data 传递给子节点 父容器设置 childrenData ...

  2. Omi教程-组件通讯攻略大全

    组件通讯 Omi框架组建间的通讯非常遍历灵活,因为有许多可选方案进行通讯: 通过在组件上声明 data-* 传递给子节点 通过在组件上声明 data 传递给子节点 (支持复杂数据类型的映射) 父容器设 ...

  3. Omi教程-使用group-data通讯

    写在前面 Omi框架组建间的通讯非常遍历灵活,上篇文章介绍了几种通讯方式,其中childrenData的方式可以批量传递数据给组件,但是有很多场景下data的来源不一定非要都从childrenData ...

  4. Omi教程-通讯通讯攻略大全

    组件通讯 Omi框架组建间的通讯非常遍历灵活,因为有许多可选方案进行通讯: 通过在组件上声明 data-* 传递给子节点 通过在组件上声明 data 传递给子节点 (支持复杂数据类型的映射) 父容器设 ...

  5. Omi教程-生命周期和事件处理

    生命周期 名称 含义 时机 constructor 构造函数 new的时候 install 初始化安装,这可以拿到用户传进的data进行处理 实例化 installed 安装完成,HTML已经插入页面 ...

  6. Omi教程-插件体系

    插件体系 Omi是Web组件化框架,怎么又来了个插件的概念? 可以这么理解: Omi插件体系可以赋予dom元素一些能力,并且可以和组件的实例产生关联. omi-drag 且看这个例子: 点击这里→在线 ...

  7. Omi树组件omi-tree编写指南

    Omi框架能够以少量的代码声明式地编写可拖拽移动节点的树形组件. 通常树组件能够考验UI框架的健壮性,因为需要使用到UI框架的如下特性: 组件嵌套 组件传值 组件批量传值 组件依赖自身递归嵌套(nes ...

  8. PyQt5教程——组件 Ⅱ(八)

    这部分的教程将会继续介绍PyQt5的组件.我们这节教程的内容将包括像素图(QPixmap),单行文本框(QLineEdit)和下拉列表框(QComboBox) 像素图(QPixmap) 像素图(QPi ...

  9. PyQt5教程——组件(7)

    PyQt5中的组件(widgets) 组件(widgets)是构建一个应用的基础模块.PyQt5有广泛的各式各样的组件,包含按钮,复选按钮,滑块条,和列表框.在这个部分的教程中,我们将学习几种有用的组 ...

随机推荐

  1. c#之从服务器下载压缩包,并解压

    项目的配置文件为了和服务器保持一致,每次打包时都从网上下载配置文件,由于下载的是zip压缩包,还需要解压,代码如下: using ICSharpCode.SharpZipLib.Zip; using ...

  2. libtask channel机理及调度理解

    学习golang的时候libtask库的代码是一定要看的,需要深入理解chan和携程的运行机制,下面就结合libtask的源码说明下运行原理,如果理解的有偏差欢迎指正 下面是libtask中Chann ...

  3. linux下JUCE源码编译依赖库

    JUCE 源码https://github.com/julianstorer/JUCE 想在ubuntu下编译需要提前安装以下依赖库 sudo apt-get install mesa-common- ...

  4. iOS 之 时间格式与字符串转换

    这个知识点涉及到三个类:NSDate.NSString,另外是一个最重要的类NSDateFormatter.它起到格式转换的作用,至于方法查看头文件就好了.时间格式注意下:yyyyMMddHHmmss

  5. Prism之使用EventAggregation进行模块间通信

    在开发Silverlight程序的时候,经常需要在不同的组件间进行通信.比如点击一个button,可能就需要改变另一个控件的内容.比较直接的办法是使用事件,当然使用MVVM的时候也可以使用comman ...

  6. 配置tomcat及如何自动编译jsp文件

    1.myeclipse如何关联tomcat? 四个注意点...  必须一致! 2.别人修改过jsp不用重启服务器,我的却要每次重启服务器,网上找了很多方法都没有用,很是郁闷...最后发现了原来是bui ...

  7. OC--设置视图控制器,从导航栏的下边缘开始

    self.edgesForExtendedLayout = UIRectEdgeNone;

  8. Python3基础 global关键字 使函数的局部变量升格为全局变量

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...

  9. 论MySQL数据库中两种数据引擎的差别

    InnoDB和MyISAM是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定. 基本的差别为: MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持. MyISAM类型的表强 ...

  10. Angular - - ngList、ngRepeat、ngModelOptions

    ngList 在文本输入的分隔的字符串和字符串数组间做转换,可以是一个固定的字符串分隔符(默认逗号)或正则表达式. 格式:ng-list=”value” value:表达式  通过这个值分隔字符串. ...