Omi框架学习之旅 - 组件通讯(data通讯) 及原理说明
接着上一篇的data-*通讯,这篇写data通讯。
data通讯主要为了复杂的数据通讯。
老规矩:先上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}}! </h1> </div> `; } }; Omi.makeHTML('Hello', Hello); class App extends Omi.Component { constructor(data) { super(data); this.helloData = { name: 'Sorrow.X' }; this.complexData = { a: { b: { c: [ { e: [ { name: 'ComplexData Support1' }, { name: 'ComplexData Support2' } ] }, { name: 'ComplexData Support3' } ] } } }; } render() { return ` <div> <Hello data="helloData" /> <Hello data="complexData.a.b.c[1]" /> <Hello data="complexData.a.b.c[0].e[0]" /> </div> `; } }; var app = new App(); Omi.render(app, 'body');
个人说明:
data通讯可以支持复杂数据的原理很简单,omi会自动从父组件的实例属性上去寻找data="xxx"后面的xxx对应的实例的属性,找到后,然后把属性值浅拷贝到子类的data上,然后就可以开心的使用了。
文档地址:https://alloyteam.github.io/omi/website/docs-cn.html#
接下来说说这个demo的疑问和疑问的说明:
疑问1:
helloData和complexData.a.b.c[1]是干啥的?
答:其实上面的个人说明已经回答过了,那怎么实现的呢,如下:
来进入1的方法去看看:
_extractPropertyFromString(str, instance){ // str: data的属性值, instance: Component子类的实例 let arr = str.replace(/['|"|\]]/g,'' ).replace(/\[/g,'.').split('.'); // 把字符串转换成数组 let current = instance; arr.forEach(prop => { current = current[prop]; // 把每次得到的结果然后在这个结果上看看有没有对应的属性(涨姿势了) }); arr = null; return current; // 返回 从实例身上获取str属性的值 }
找到属性对应的属性值后,就合并数据,创建实例,后面一样了。
ps:
data方式通讯是一锤子买卖。后续变更只能通过组件实例下的data属性去更新组件。
忘了说,提取标签上的属性使用的是html2json.js很不错,感兴趣的可以研究一下源码。
开心的做一个无忧无虑的码农,争取每天进步一点。