上一篇文章说了omi中的组件,以及组件如何使用及嵌套。
那omi中的组件是怎么通讯的呢?
其实omi提供的通讯方式比较丰富,各有千秋,各有各的场景用途。所以按需使用即可。
老规矩:先上demo代码, 然后提出问题, 之后解答问题, 最后源码说明。
class Hello extends Omi.Component { constructor(data) { super(data); } style() { return ` h1 { cursor: pointer; } `; } handleClick(target, click) { console.log(target.innerHTML); } render() { return ` <div> <h1 onclick="handleClick(this, event)"> Hello, {{name}}! {{str}} {{bool}} {{num}} {{arr}} </h1> </div> `; } }; Omi.makeHTML('Hello', Hello); class App extends Omi.Component { constructor(data) { super(data); } render() { return ` <div> <Hello name='hel' data-name = "Sorrow.X" data-str = "str"/> <Hello data-bool = true data-num = 111/> </div> `; } }; var app = new App(); Omi.render(app, 'body'); setTimeout(() => { app.hel.data.name ='名字'; app.hel.data.name ='str字符串'; app.hel.update(); }, 2000);
先看看omi中文文档的说明:
一般data-用来传递值类型,如string、number。值得注意的是,通过data-接收到的数据类型都是string,需要自行转成number类型。
文档地址:https://alloyteam.github.io/omi/website/docs-cn.html#
接下来说说这个demo的疑问和疑问的说明:
疑问1:
data-xxx后面的名字可以直接用在子类(这里指的是Hello)的render方法中吗?
答:是的,作者是这么做到的。如下
往下看
我们来看看1这里的代码:
_capitalize (str){ // data-xxx后面的xxx字符串 str = str.toLowerCase(); str = str.replace(/w+/g, function (word) { return word.substring(0, 1).toUpperCase() + word.substring(1); }).replace(/-/g,''); // 第一个字母大写后面的小写 return str.substring(0, 1).toLowerCase() + str.substring(1); // 第一个字母小写后面的小写(全都小写) }
之后得到dataset对象,里面有我们设置的值啦。
然后就new 子类的实例,然后sub_child._childRender(childStr,true);(说明: 这里其实帮我们生成了子类的html和css还有事件的转换,组件那篇文章已经说过了)。
之后就把该数据dataset给了子类实例的data属性(此demo只有dataset有数据合并了,如果其他对象有数据依次合并,属性相同的话,后面的会覆盖前面的Object.assign(baseData,child.childrenData[i],dataset,dataFromParent,groupData ))。
疑问2:
同一个Hello标签可以多次使用吗?
答:那肯定撒,作者是这么做到的,如下:
其实是遍历了2次
那怎么合并到父组件中呢,其实回到_render方法中,如下
然后渲染到dom中去了。
然后就这么结束了。
ps:通过data-✼通讯也是一锤子买卖。后续变更只能通过组件实例下的data属性去更新组件。
所以最好指定子类的实例名比如name=hel,如demo中的,可以跟新数据。
也可以指定omi-id,后续再讲。