Hello Omi
Omi框架的每個元件都繼承自Omi.Component,本篇會去完成Omi的Component的基本錐形,讓其能夠渲染第一個元件。
omi.js實現
var Omi = {};
Omi._instanceId = 0;
Omi.getInstanceId = function () {
return Omi._instanceId++;
};
Omi.render = function(component, renderTo){
component.renderTo = typeof renderTo === "string" ? document.querySelector(renderTo) : renderTo;
component._render();
return component;
};
module.exports = Omi;
- Omi.getInstanceId 用來給每個元件生成自增的ID
- Omi.render 用來把元件渲染到頁面
基類Omi.Component實現
所有的元件都是繼承自Omi.Component。
import Omi from './omi.js';
class Component {
constructor(data) {
this.data = data || {};
this.id = Omi.getInstanceId();
this.HTML = null;
this.renderTo = null;
}
_render() {
this.HTML = this.render();
this.renderTo.innerHTML = this.HTML;
}
}
export default Component;
- Omi使用完全物件導向的方式去開發元件,這裡約定好帶有下劃線的方法是用於內部實現呼叫,不建議Omi框架的使用者去呼叫。
- 其中,_render為私有方法用於內部實現呼叫,會去呼叫元件的真正render方法用於生成HTML,並且把生成的HTML插入到renderTo容器裡面。
- 注意,這裡目前沒有引入dom diff,不管第幾次渲染都是無腦設定innerHTML,複雜HTML結構對瀏覽器的開銷很大,這裡後續會引入diff。
index.js整合
import Omi from './omi.js';
import Component from './component.js';
Omi.Component = Component;
window.Omi = Omi;
module.exports = Omi;
這裡把Omi給直接暴露在window下,因為每個元件都生成了唯一的ID,後續實現事件作用域以及物件例項獲取都要通過window下的Omi獲取。
最後使用
實現完omi.js和component.js以及index.js之後,你就可以實現Hello Omi拉:
import Omi from 'index.js';
//或者使用webpack build之後的omi.js
//import Omi from 'omi.js';
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
render() {
return `
<div>
<h1>Hello ,`+ this.data.name +`!</h1>
</div>
`;
}
}
Omi.render(new Hello({ name : 'Omi' }),"#container");
什麼?都2017年了還在拼接字串?!雖然ES6+的template string讓多行字串拼接更加得心應手,但是template string+模板引擎可以讓更加優雅方便。既然用了template string,也可以寫成這樣子:
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
render() {
return `
<div>
<h1>Hello ,${this.data.name}!</h1>
</div>
`;
}
}
Omi.render(new Hello({ name : 'Omi' }),"#container");
引入mustachejs模板引擎
Omi支援任意模板引擎。可以看到,上面是通過拼接字串的形式生成HTML,這裡當然可以使用模板引擎。
修改一下index.js:
import Omi from './omi.js';
import Mustache from './mustache.js';
import Component from './component.js';
Omi.template = Mustache.render;
Omi.Component = Component;
window.Omi=Omi;
module.exports = Omi;
這裡把Mustache.render掛載在Omi.template下。再修改一下component.js:
import Omi from './omi.js';
class Component {
constructor(data) {
this.data = data || {};
this.id = Omi.getInstanceId();
this.HTML = null;
}
_render() {
this.HTML = Omi.template(this.render(), this.data);
this.renderTo.innerHTML = this.HTML;
}
}
export default Component;
Omi.template(即Mustache.render)需要接受兩個引數,第一個引數是模板,第二個引數是模板使用的資料。
現在,你便可以使用mustachejs模板引擎的語法了:
class Hello extends Omi.Component {
constructor(data) {
super(data);
}
render() {
return `
<div>
<h1>Hello ,{{name}}!</h1>
</div>
`;
}
}
從上面的程式碼可以看到,你完全可以重寫Omi.template方法去使用任意模板引擎。重寫Omi.template的話,建議使用omi.lite.js,因為omi.lite.js是不包含任何模板引擎的。那麼怎麼build出兩個版本的omi?且看webpack裡設定的多入口:
entry: {
omi: './src/index.js',
'omi.lite': './src/index.lite.js'
},
output: {
path: 'dist/',
library:'Omi',
libraryTarget: 'umd',
filename: '[name].js'
},
index.lite.js的程式碼如下:
import Omi from './omi.js';
import Component from './component.js';
Omi.template = function(tpl, data){
return tpl;
}
Omi.Component = Component;
window.Omi=Omi;
module.exports = Omi;
可以看到Omi.template沒有對tpl做任何處理直接返回,開發者可以重寫該方法。
總結
到目前為止,已經實現了:
- 第一個元件的渲染
- 模板引擎的接入
- 多入口打包omi.js和omi.lite.js
下片,將介紹《Omi原理-區域性CSS》,歡迎關注...
招募計劃
- 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)