組件通訊 "Omi框架" 組建間的通訊非常遍歷靈活,因為有許多可選方案進行通訊: 通過在組件上聲明 data 傳遞給子節點 通過在組件上聲明 data 傳遞給子節點 (支持複雜數據類型的映射) 父容器設置 childrenData 自動傳遞給子節點 聲明 group data 傳遞(支持複雜數據類型 ...
組件通訊
Omi框架組建間的通訊非常遍歷靈活,因為有許多可選方案進行通訊:
- 通過在組件上聲明 data-* 傳遞給子節點
- 通過在組件上聲明 data 傳遞給子節點 (支持複雜數據類型的映射)
- 父容器設置 childrenData 自動傳遞給子節點
- 聲明 group-data 傳遞(支持複雜數據類型的映射)
- 完全面向對象,可以非常容易地拿到對象的實例,之後可以設置實例屬性和調用實例的方法
所以通訊變得暢通無阻,下麵一一來舉例說明。
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通訊,請往下看。
data通訊
如上面代碼所示,通過 data-name="Omi"可以把name傳遞給子組件。下麵的代碼也可以達到同樣的效果。
...
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>
`;
}
}
...
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裡面的組件會一一對應上。
group-data通訊
childrenData的方式可以批量傳遞數據給組件,但是有很多場景下data的來源不一定非要都從childrenData來,childrenData是個數組,會和組件的順序一一對應,這就給不同傳遞方式的data必須全部集中的childrenData中,非常不方便。group-data專門為解決上面的痛點而生,專門是為了給一組組件批量傳遞data。
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)下麵找對應的屬性,然後根據當前的位置,和對應數組的位置會一一對應起來。
運行結果如下:
同樣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");
通過對象實例
...
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-✼);
}
招募計劃
- 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)