博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Omi 6.0 - Store 的设计哲学
阅读量:5986 次
发布时间:2019-06-20

本文共 3826 字,大约阅读时间需要 12 分钟。

写在前面

Store 是 Omi 内置的中心化数据仓库,他解决了下面两个问题:

  • 组件树数据共享
  • 数据变更按需更新依赖的组件

而这一切都是在运行时搞定。

一段代码完全上手 Store

import { render, WeElement, define } from 'omi'define('my-counter', class extends WeElement {  static use = [    { count: 'count' }  ]  add = () => this.store.add()  sub = () => this.store.sub()  addIfOdd = () => {    if (this.use.count % 2 !== 0) {      this.store.add()    }  }  addAsync = () => {    setTimeout(() => this.store.add(), 1000)  }  render() {    return (      

Clicked: {this.use.count} times {' '} {' '} {' '} {' '}

) }})render(
, 'body', { data: { count: 0 }, sub() { this.data.count-- }, add() { this.data.count++ },})复制代码

这是一个简单的例子,说明了 store 体系的基本用法:

  • 通过 static use 声明依赖的 path
  • store 通过 render 的第三个参数从根节点注入到所有组件。
  • 调用组件的方法或者直接改变组件的 data 进行视图更新

这里在书写过程中会出现两种方式,一种是将所有数据和逻辑放在 store 里,一种是将部分共享数据放在 store 里,这里没有强制要求使用哪种方式,omi 这两种能力都有,开发者偏爱哪种方式就使用哪种方式。

复杂的例子

Store 里的 data:

{  count: 0,  arr: ['china', 'tencent'],  motto: 'I love omi.',  userInfo: {    firstName: 'dnt',    lastName: 'zhang',    age: 18  }}复制代码

Static use:

static use = [  'count', //直接字符串,可通过 this.use[0] 访问  'arr[0]', //也支持 path,可通过 this.use[1] 访问  //支持 json  {    //alias,可通过 this.use.reverseMotto 访问    reverseMotto: [      'motto', //path      target => target.split('').reverse().join('')  //computed    ]  },  { name: 'arr[1]' }, //{ alias: path },可通过 this.use.name 访问  {    //alias,可通过 this.use.fullName 访问    fullName: [      ['userInfo.firstName', 'userInfo.lastName'], //path array      (firstName, lastName) => firstName + lastName //computed    ]  },]复制代码

下面看看 JSX 中使用:

......render() {  return (    
{this.use[0]}
{this.use[1]}
{this.use.reverseMotto}
{this.use.name}
{this.use[3]}
{this.use.fullName}
)}......复制代码

如果不带有 alias ,你也可以直接通过 this.store.data.xxx 访问。

Path 命中规则

store.data 发生变化,依赖变更数据的组件会进行更新,举例说明 Path 命中规则:

Proxy Path(由数据更改产生) static use 中的 path 是否更新
abc abc 更新
abc[1] abc 更新
abc.a abc 更新
abc abc.a 不更新
abc abc[1] 不更新
abc abc[1].c 不更新
abc.b abc.b 更新

以上只要命中一个条件就可以进行更新!

总结: 只要注入组件的 path 等于 use 里声明 或者在 use 里声明的其中 path 子节点下就会进行更新!

解构赋值

import { define, WeElement } from 'omi'import '../my-list'define('my-sidebar', class extends WeElement {  static css = require('./_index.css')  static use = [    'menus',    'sideBarShow',    'lan'  ]  render() {    const [menus, sideBarShow, lan] = this.use    return (      
{menus[lan].map((menu, index) => (
))}
) }})复制代码

这里举了个例子使用 ES2015+ 语法 const [xx, xxx] = xxxx 的语法快速赋值。上面是从 的源码里截取的部分。感兴趣的可以。omi 官网已经使用 omi 6.0 重写了。

设计哲学

回顾 Omi 从 1.0 到 6.0:

  • Omi 1.0 运行时动态模板引擎
  • Omi 2.0 拥抱虚拟 DOM 和运行时 scoped style
  • Omi 3.0 提供 native 模块调用 bridge
  • Omi 4.0 拥抱 Web Components
  • Omi 5.0 纠正社区对 MVVM 误解
  • Omi 6.0 拥抱多端统一,迎来全新 path updating 的 store 体系

1.0 使用的动态模板引擎,是图灵完备的,可以表达一切你想表达的结构。由于是运行时,没法转虚拟 DOM,一定要转也可以,开销大,所以缺点很明显,视图更新开销大,依赖真实 DOM 之间的的 diff,另外一个缺点就是动态模板引擎(指令、模板语法都可以动态拼接)需要在脑海里二次转换,书写起来不够直观、智能提示也没有,不如 JSX 直接干净和智能。而为什么要这么设计,从整个发展历程来看离不开三个字: 运行时

Omi 的设计 1.0 败也败在运行时,成也成在运行时。从 2.0 开始,除了 JSX 的部分(当然可以直接 hyperscript),其余全部 运行时 搞定:

  • 运行时的 scoped style
  • 运行时的 path updating 局部刷新

而到了 9210 年,JSX 也出现了运行时的替代方案: 。

为何如此偏爱运行时?而不交给编译器去做?这个仁者见仁,智者见智,而且有个权衡在里面。

当运行时的开销对于用户体验可以忽略不计,那么就选择运行时去做

运行时的好处非常明显,不需要任何构建工具、编译工具,就可以在浏览器、node、javascript core 或者任何 javascript 环境直接运行。凭什么让我学那么多构建工具、凭什么和一堆工具耦合在一起,我就是纯粹的 js,想在哪里跑都可以轻松复制粘贴或者直接 import/require 过去,而不强制带上任何工具。当然这里不是反对编译工具对前端带来的价值,omi-cli、omip、omi-mp 都大量使用了编译工具,只是没有编译工具,omi 也能运行良好,简单移植,比如 es module,比如 deno,直接 import 直接使用。

开始使用

转载地址:http://esflx.baihongyu.com/

你可能感兴趣的文章
进程和线程之间的关系.
查看>>
总结CString、string、char*
查看>>
设置listview,隔行不同style
查看>>
【eoe Android特刊】第二十五期 Android 应用的终端适配
查看>>
Java菜鸟零基础自学入门必备视频教程
查看>>
Git忽略规则和.gitignore规则不生效的解决办法
查看>>
php实现汉诺塔问题
查看>>
linux c++ sqlite3
查看>>
Eclipse自动生成作者、日期注释等功能设置
查看>>
MySQL 按时间统计
查看>>
SSL双向认证
查看>>
go语言的time包
查看>>
sheepdog安装和使用管理
查看>>
mycncart 之 支付宝手机网页即时到帐支付方式
查看>>
[Android]ContentProvider会用到的ProjectionMap的用处
查看>>
[Android]Linux BASH脚本中cmp比较命令的应用例子
查看>>
iptables规则备份与恢复, firewalld介绍
查看>>
内存对齐
查看>>
Exchange日常管理之二十:代表发送与代理发送
查看>>
while+case
查看>>