元件
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的Github地址https://github.com/AlloyTeam/omi
- 如果想體驗一下Omi框架,請點選Omi Playground
- 如果想使用Omi框架,請閱讀 Omi使用文件
- 如果想一起開發完善Omi框架,有更好的解決方案或者思路,請閱讀 從零一步步打造web元件化框架Omi
- 關於上面的兩類文件,如果你想獲得更佳的閱讀體驗,可以訪問Docs Website
- 如果你懶得搭建專案腳手架,可以試試Scaffolding for Omi,npm安裝omis便可
- 如果你有Omi相關的問題可以New issue
- 如果想更加方便的交流關於Omi的一切可以加入QQ的Omi交流群(256426170)