put in order

This commit is contained in:
dntzhang 2018-10-20 14:20:44 +08:00
parent 52be4886e7
commit a2d7b9fc20
71 changed files with 0 additions and 1371 deletions

View File

@ -1,14 +0,0 @@
node_modules
/node_modules
/npm-debug.log
.DS_Store
/_dev
/coverage
package-lock.json
/test/ts/**/*.js
# Editor and IDE configuration
.vscode/
.idea/
/plugins/*/node_modules

View File

@ -1,25 +0,0 @@
# Contributing
欢迎任意形式的贡献。
## Acknowledgements
非常感谢以下几位贡献者对于 Omi 的做出的贡献:
* vorshen <987733967@qq.com>
* pasturn <pasturn@qq.com>
* xcatliu <xcatliu@gmail.com>
vorshen 对 omi 进行了全面充分的测试和实践,发现并解决了许多隐藏很深的问题,对 omi 体系的 scoped css 献计献策,修复了多处 bug贡献巨大。
pasturn 是 omi-cli pasturn 不断优化 cli 的体验,让开发者从安装到使用过程行云流水,挥洒自如,贡献巨大。
xcatliu 在微软工作期间,就积极参与 omi 的翻译工作,后来要参与的 omi scoped css 的设计和开发工作,贡献巨大。
*以上贡献者已由腾讯开源官方发放优秀贡献者证书
## 腾讯开源贡献者激励
我们非常欢迎开发者们为腾讯开源贡献一份力量,相应也将给予贡献者激励以表认可与感谢。在此我们提供了官方对腾讯开源贡献的说明文档,每个项目的具体贡献规则由项目团队制定,开发者可以选择适合的项目并根据对应规则参与。腾讯项目管理委员会将定期上报满足条件的贡献者,后续将由官方联系发放奖励。
详情https://opensource.tencent.com/contribution

View File

@ -1,34 +0,0 @@
Tencent is pleased to support the open source community by making Omi available.
Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.
If you have downloaded a copy of the Omi binary from Tencent, please note that the Omi binary is licensed under the MIT License.
If you have downloaded a copy of the Omi source code from Tencent, please note that Omi source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of Omi into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within Omi.
A copy of the MIT License is included in this file.
Open Source Software Licensed Under the MIT License:
------------------------------------------------------
preact 8.2.7
Copyright (c) 2017 Jason Miller
jsonpatcherproxy 0.0.10
Copyright (c) 2018 alshakero
The MIT License (MIT)
------------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,402 +0,0 @@
[English](./README.md) | 简体中文
# Omi - 合一 (支持IE11的版本)
> 下一代 Web 框架,去万物糟粕,合精华为一。
<p align="center"><img src="./assets/omi.png" alt="omi"/></p>
### 特性
- 4KB 的代码尺寸,比小更小
- 顺势而为,顺从浏览器的发展和 API 设计
- Web Components + JSX 相互融合为一个框架 Omi
- Web Components 也可以数据驱动视图, UI = fn(data)
- JSX 是开发体验最棒(智能提示)、[语法噪音最少](https://github.com/facebook/jsx#why-not-template-literals)的 UI 表达式
- 独创的 Path Updating 机制,基于 Proxy 全自动化的精准更新,功耗低,自由度高,性能卓越,方便集成 requestIdleCallback
- 使用 store 系统不需要调用 this.udpate它会自动化按需更新局部视图
- 看看[Facebook React 和 Web Components对比优势](https://www.cnblogs.com/rubylouvre/p/4072979.html)Omi 融合了各自的优点,而且给开发者自由的选择喜爱的方式
- Shadom DOM 与 Virtual DOM 融合Omi 既使用了虚拟 DOM也是使用真实 Shadom DOM让视图更新更准确更迅速
- 类似 WeStore 体系99.9% 的项目不需要什么时间旅行,也不仅仅 redux 能时间旅行,请不要上来就 reduxOmi store 体系可以满足所有项目
- 局部 CSS 最佳解决方案(Shadow DOM),社区为局部 CSS 折腾了不少框架和库(使用js或json写样式如:Radiumjsxstylereact-style与webpack绑定使用生成独特的className`文件名—类名—hash值`CSS ModulesVue),都是 hack 技术Shadow DOM Style 是最完美的方案
对比同样开发 TodoApp Omi 和 React 渲染完的 DOM 结构:
![](./assets/omi-render.jpg) ![](./assets/react-render.jpg)
左边是Omi右边是 ReactOmi 使用 Shadow DOM 隔离样式和语义化结构。
---
- [文档](https://github.com/Tencent/omi/blob/master/docs/main-concepts.cn.md)
- [一个 HTML 完全上手](#一个-html-完全上手)
- [Getting Started](#getting-started)
- [Install](#install)
- [Hello Element](#hello-element)
- [TodoApp](#todoapp)
- [Store](#store)
- [生命周期](#生命周期)
- [生态](#生态)
- [浏览器兼容](#浏览器兼容)
- [Links](#links)
- [License](#license)
## 一个 HTML 完全上手
下面这个页面不需要任何构建工具就可以执行
* [点击这里看执行结果](https://tencent.github.io/omi/assets/)。
* [Omi.js CDN](https://unpkg.com/omi)
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Add Omi in One Minute</title>
</head>
<body>
<script src="https://unpkg.com/omi"></script>
<script>
const { WeElement, h, render, define } = Omi
class LikeButton extends WeElement {
install() {
this.data = { liked: false }
}
render() {
if (this.data.liked) {
return 'You liked this.'
}
return h(
'button',
{
onClick: () => {
this.data.liked = true
this.update()
}
},
'Like'
)
}
}
define('like-button', LikeButton)
render(h('like-button'), 'body')
</script>
</body>
</html>
```
## Getting Started
### Install
```bash
$ npm i omi-cli -g # install cli
$ omi init your_project_name # init project, you can also exec 'omi init' in an empty folder
$ cd your_project_name # please ignore this command if you executed 'omi init' in an empty folder
$ npm start # develop
$ npm run build # release
```
Cli 自动创建的项目脚手架是基于单页的 create-react-app 改造成多页的,有配置方面的问题可以查看 [create-react-app 用户指南](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md)。
### Hello Element
先创建一个自定义元素:
```js
import { tag, WeElement, render } from 'omi'
@tag('hello-element')
class HelloElement extends WeElement {
onClick = (evt) => {
//trigger CustomEvent
this.fire('abc', { name : 'dntzhang', age: 12 })
evt.stopPropagation()
}
css() {
return `
div{
color: red;
cursor: pointer;
}`
}
render(props) {
return (
<div onClick={this.onClick}>
Hello {props.msg} {props.propFromParent}
<div>Click Me!</div>
</div>
)
}
}
```
使用该元素:
``` js
import { tag, WeElement, render } from 'omi'
import './hello-element'
@tag('my-app')
class MyApp extends WeElement {
static get data() {
return { abc: '', passToChild: '' }
}
//bind CustomEvent
onAbc = (evt) => {
// get evt data by evt.detail
this.data.abc = ' by ' + evt.detail.name
this.update()
}
css() {
return `
div{
color: green;
}`
}
render(props, data) {
return (
<div>
Hello {props.name} {data.abc}
<hello-element onAbc={this.onAbc} prop-from-parent={data.passToChild} msg="WeElement"></hello-element>
</div>
)
}
}
render(<my-app name='Omi v4.0'></my-app>, 'body')
```
告诉 Babel 把 JSX 转化成 Omi.h() 的调用:
``` json
{
"presets": ["env", "omi"]
}
```
需要安装下面两个 npm 包支持上面的配置:
``` bash
"babel-preset-env": "^1.6.0",
"babel-preset-omi": "^0.1.1",
```
如果不想把 css 写在 js 里,你可以使用 [to-string-loader](https://www.npmjs.com/package/to-string-loader), 比如下面配置:
``` js
{
test: /[\\|\/]_[\S]*\.css$/,
use: [
'to-string-loader',
'css-loader'
]
}
```
如果你的 css 文件以 `_` 开头, css 会使用 to-string-loader. 如:
``` js
import { tag, WeElement render } from 'omi'
//typeof cssStr is string
import cssStr from './_index.css'
@tag('my-app')
class MyApp extends WeElement {
css() {
return cssStr
}
...
...
...
```
### TodoApp
下面列举一个相对完整的 TodoApp 的例子:
```js
import { tag, WeElement, render } from 'omi'
@tag('todo-list')
class TodoList extends WeElement {
render(props) {
return (
<ul>
{props.items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
}
@tag('todo-app')
class TodoApp extends WeElement {
static get data() {
return { items: [], text: '' }
}
render() {
return (
<div>
<h3>TODO</h3>
<todo-list items={this.data.items} />
<form onSubmit={this.handleSubmit}>
<input
id="new-todo"
onChange={this.handleChange}
value={this.data.text}
/>
<button>
Add #{this.data.items.length + 1}
</button>
</form>
</div>
);
}
handleChange = (e) => {
this.data.text = e.target.value
}
handleSubmit = (e) => {
e.preventDefault();
if (!this.data.text.trim().length) {
return;
}
this.data.items.push({
text: this.data.text,
id: Date.now()
})
this.data.text = ''
}
}
render(<todo-app></todo-app>, 'body')
```
### Store
使用 Store 体系可以告别 update 方法,基于 Proxy 的全自动属性追踪和更新机制。强大的 Store 体系是高性能的原因,除了靠 props 决定组件状态的组件,其余组件所有 data 都挂载在 store 上,
```js
export default {
data: {
items: [],
text: '',
firstName: 'dnt',
lastName: 'zhang',
fullName: function () {
return this.firstName + this.lastName
},
globalPropTest: 'abc', //更改我会刷新所有页面,不需要再组件和页面声明data依赖
ccc: { ddd: 1 } //更改我会刷新所有页面,不需要再组件和页面声明data依赖
},
globalData: ['globalPropTest', 'ccc.ddd'],
add: function () {
if (!this.data.text.trim().length) {
return;
}
this.data.items.push({
text: this.data.text,
id: Date.now()
})
this.data.text = ''
}
//默认 false为 true 会无脑更新所有实例
//updateAll: true
}
```
自定义 Element 需要声明依赖的 data这样 Omi store 根据自定义组件上声明的 data 计算依赖 path 并会按需局部更新。如:
```js
class TodoApp extends WeElement {
static get data() {
//如果你用了 store这个只是用来声明依赖按需 Path Updating
return { items: [], text: '' }
}
...
...
...
handleChange = (e) => {
this.store.data.text = e.target.value
}
handleSubmit = (e) => {
e.preventDefault()
this.store.add()
}
}
```
* 数据的逻辑都封装在了 store 定义的方法里 (如 store.add)
* 视图只负责传递数据给 store (如上面调用 store.add 或设置 store.data.text
需要在 render 的时候从根节点注入 store 才能在所有自定义 Element 里使用 this.store:
```js
render(<todo-app></todo-app>, 'body', store)
```
[→ Store 完整的代码](https://github.com/Tencent/omi/blob/master/packages/omi/examples/store/main.js)
总结一下:
* store.data 用来列出所有属性和默认值(除去 props 决定的视图的组件)
* 组件和页面的 data 用来列出依赖的 store.data 的属性 (omi会记录path),按需更新
* 如果页面简单组件很少,可以 updateAll 设置成 true并且组件和页面不需要声明 data也就不会按需更新
* globalData 里声明的 path只要修改了对应 path 的值就会刷新所有页面和组件globalData 可以用来列出所有页面或大部分公共的属性 Path
### 生命周期
| Lifecycle method | When it gets called |
|-------------------------------|--------------------------------------------------|
| `install` | before the component gets mounted to the DOM |
| `installed` | after the component gets mounted to the DOM |
| `uninstall`     | prior to removal from the DOM                   |
| `beforeUpdate` | before `render()` |
| `afterUpdate` | after `render()` |
## 生态
* [https://www.webcomponents.org/](https://www.webcomponents.org/)
* [https://www.webcomponents.org/elements](https://www.webcomponents.org/elements)
在里面查找你想要的组件,直接使用,或者花几分钟就能转换成 Omi Element把模板拷贝到 render 方法style拷贝到 css 方法)。
## 浏览器兼容
Omi 4.0+ works in the latest two versions of all major browsers: Safari 10+, IE 11+, and the evergreen Chrome, Firefox, and Edge.
![Browsers Support](./assets/browsers-support.png)
[→ polyfills](https://github.com/webcomponents/webcomponentsjs)
## Links
- [westore](https://github.com/dntzhang/westore)
- [omijs.org](http://omijs.org/)
## License
MIT © Tencent
Please contact me[@dntzhang](https://github.com/dntzhang) for any questions.

View File

@ -1,409 +0,0 @@
English | [简体中文](./README.CN.md)
# Omi (Compatible with IE11)
> Next generation web framework in 4KB javascript(Merge JSX, Web Components, Proxy, Path Updating together).
<p align="center"><img src="./assets/omi.png" alt="omi"/></p>
### Why Omi
- Tiny size(4KB gzip)
- Support TypeScript
- Reactive data-binding
- Compliance with browser trend and API design
- Merge JSX and Web Components into One Framework
- Web Components can also be a data-driven view, UI = fn(data)
- JSX is the best development experience (code intelligent completion and tip) UI Expression with least [grammatical noise](https://github.com/facebook/jsx#why-not-template-literals)
- The original Path Updating system. Proxy-based automatic accurate update, low power consumption, high degree of freedom, excellent performance, easy integration of requestIdleCallback
- Say goodbye to `this.update` method when using store system! It will update partial UI automatically when data changed.
- Look at [Facebook React VS Web Components](https://softwareengineering.stackexchange.com/questions/225400/pros-and-cons-of-facebooks-react-vs-web-components-polymer)Omi combines their advantages and gives developers the freedom to choose the way they like.
- Shadom DOM merges with Virtual DOM, Omi uses both virtual DOM and real Shadom DOM to make view updates more accurate and faster
- With a Store system, 99.9% of projects don't need time travel, and not only Redux can travel, please don't come up on redux, Omi store system can meet all projects
- Scoped CSS's best solution is Shadow DOM, the community churning out frameworks and libraries for Scoped CSS (using JS or JSON writing styles such as Radium, jsxstyle, react-style; binding to webpack using generated unique className `filename-classname-hash', such as CSS Modules, Vue), are hack technologies; and Shadow DOM Style is the perfect solution.
Compare TodoApp by Omi and React, Omi and React rendering DOM structure:
![](./assets/omi-render.jpg) ![](./assets/react-render.jpg)
On the left is Omi, the right side is React, and Omi uses Shadow DOM isolation style and semantic structure.
---
- [Docs](https://github.com/Tencent/omi/blob/master/docs/main-concepts.md)
- [Add Omi in One Minute](#add-omi-in-one-minute)
- [Getting Started](#getting-started)
- [Install](#install)
- [Hello Element](#hello-element)
- [TodoApp](#todoapp)
- [Store](#store)
- [Lifecycle](#lifecycle)
- [Component Ecosystem](#component-ecosystem)
- [Browsers Support](#browsers-support)
- [Links](#links)
- [License](#license)
## Add Omi in One Minute
This page demonstrates using Omi with no build tooling.
* [Online Demo!](https://tencent.github.io/omi/assets/)
* [Omi.js CDN](https://unpkg.com/omi)
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Add Omi in One Minute</title>
</head>
<body>
<script src="https://unpkg.com/omi"></script>
<script>
const { WeElement, h, render, define } = Omi
class LikeButton extends WeElement {
install() {
this.data = { liked: false }
}
render() {
if (this.data.liked) {
return 'You liked this.'
}
return h(
'button',
{
onClick: () => {
this.data.liked = true
this.update()
}
},
'Like'
)
}
}
define('like-button', LikeButton)
render(h('like-button'), 'body')
</script>
</body>
</html>
```
## Getting Started
### Install
```bash
$ npm i omi-cli -g # install cli
$ omi init your_project_name # init project, you can also exec 'omi init' in an empty folder
$ cd your_project_name # please ignore this command if you executed 'omi init' in an empty folder
$ npm start # develop
$ npm run build # release
```
Cli's auto-created project scaffolding is based on a single-page create-react-app to be converted into a multi-page one, with configuration issues to see [create-react-app user guide](https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md)
### Hello Element
Define a custom element:
```js
import { tag, WeElement, render } from 'omi'
@tag('hello-element')
class HelloElement extends WeElement {
onClick = (evt) => {
//trigger CustomEvent
this.fire('abc', { name : 'dntzhang', age: 12 })
evt.stopPropagation()
}
css() {
return `
div{
color: red;
cursor: pointer;
}`
}
render(props) {
return (
<div onClick={this.onClick}>
Hello {props.msg} {props.propFromParent}
<div>Click Me!</div>
</div>
)
}
}
```
Using `hello-element`:
``` js
import { tag, WeElement, render } from 'omi'
import './hello-element'
@tag('my-app')
class MyApp extends WeElement {
static get data() {
return { abc: '', passToChild: '' }
}
//bind CustomEvent
onAbc = (evt) => {
// get evt data by evt.detail
this.data.abc = ' by ' + evt.detail.name
this.update()
}
css() {
return `
div{
color: green;
}`
}
render(props, data) {
return (
<div>
Hello {props.name} {data.abc}
<hello-element onAbc={this.onAbc} prop-from-parent={data.passToChild} msg="WeElement"></hello-element>
</div>
)
}
}
render(<my-app name='Omi v4.0'></my-app>, 'body')
```
Tell Babel to transform JSX into Omi.h () call:
``` json
{
"presets": ["env", "omi"]
}
```
The following two NPM packages need to be installed to support the above configuration:
``` bash
"babel-preset-env": "^1.6.0",
"babel-preset-omi": "^0.1.1",
```
If you don't want to write CSS in js, you can use [to-string-loader](https://www.npmjs.com/package/to-string-loader),
For example, the following configuration:
``` js
{
test: /[\\|\/]_[\S]*\.css$/,
use: [
'to-string-loader',
'css-loader'
]
}
```
If your CSS file starts with "_", CSS will use to-string-loader., such as:
``` js
import { tag, WeElement render } from 'omi'
//typeof cssStr is string
import cssStr from './_index.css'
@tag('my-app')
class MyApp extends WeElement {
css() {
return cssStr
}
...
...
...
```
### TodoApp
Here is a relatively complete example of TodoApp:
```js
import { tag, WeElement, render } from 'omi'
@tag('todo-list')
class TodoList extends WeElement {
render(props) {
return (
<ul>
{props.items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
}
@tag('todo-app')
class TodoApp extends WeElement {
static get data() {
return { items: [], text: '' }
}
render() {
return (
<div>
<h3>TODO</h3>
<todo-list items={this.data.items} />
<form onSubmit={this.handleSubmit}>
<input
id="new-todo"
onChange={this.handleChange}
value={this.data.text}
/>
<button>
Add #{this.data.items.length + 1}
</button>
</form>
</div>
);
}
handleChange = (e) => {
this.data.text = e.target.value
}
handleSubmit = (e) => {
e.preventDefault();
if (!this.data.text.trim().length) {
return;
}
this.data.items.push({
text: this.data.text,
id: Date.now()
})
this.data.text = ''
this.update()
}
}
render(<todo-app></todo-app>, 'body')
```
### Store
Say goodbye to `this.update` method when using store system! It will update partial UI automatically when data changed. The powerful Store architecture is high-performance because all data is mounted on the store, except for components that rely on props to determine the state of the component.
```js
export default {
data: {
items: [],
text: '',
firstName: 'dnt',
lastName: 'zhang',
fullName: function () {
return this.firstName + this.lastName
},
globalPropTest: 'abc', //Change it will refresh all elements without changing the components and page declaring data dependency.
ccc: { ddd: 1 } //Change it will refresh all elements without changing the components and page declaring data dependency.
},
globalData: ['globalPropTest', 'ccc.ddd'],
add: function () {
if (!this.data.text.trim().length) {
return;
}
this.data.items.push({
text: this.data.text,
id: Date.now()
})
this.data.text = ''
}
//Default value is false, set to true will update all instances when data changing.
//updateAll: true
}
```
Custom Element requires declaring dependent data so that Omi stores compute the dependency path based on the data declared on the custom component and update it locally as needed. Such as:
```js
class TodoApp extends WeElement {
//If you use store, the data is only used to declare dependencies.
static get data() {
return { items: [], text: '' }
}
...
...
...
handleChange = (e) => {
this.store.data.text = e.target.value
}
handleSubmit = (e) => {
e.preventDefault()
this.store.add()
}
}
```
* the logic of data is encapsulated in the store definition method (such as store.add).
* views are only responsible for passing data to store, such as calling store.add or setting store.data.text on top.
You need to inject store from the root node at render time to use this. store:
```js
render(<todo-app></todo-app>, 'body', store)
```
[→ Store Full Code](https://github.com/Tencent/omi/blob/master/packages/omi/examples/store/main.js)
Summary
* store.data is used to list all attributes and default values (except the components of the view decided by props).
* The data of the component and page is used to list the attributes of the dependent store.data (Omi will record path) and update on demand.
* If there are few simple components on the page, updateAll can be set to true, and components and pages don't need to declare data, and they don't update on demand
* The path declared in globalData refreshes all pages and components by modifying the value of the corresponding path, which can be used to list all pages or most of the public properties Path
### Lifecycle
| Lifecycle method | When it gets called |
|-------------------------------|--------------------------------------------------|
| `install` | before the component gets mounted to the DOM |
| `installed` | after the component gets mounted to the DOM |
| `uninstall`     | prior to removal from the DOM                   |
| `beforeUpdate` | before `render()` |
| `afterUpdate` | after `render()` |
## Component Ecosystem
* [https://www.webcomponents.org/](https://www.webcomponents.org/)
* [https://www.webcomponents.org/elements](https://www.webcomponents.org/elements)
I believe you can easily convert web components elements to omi elements.
## Browsers Support
Omi 4.0+ works in the latest two versions of all major browsers: Safari 10+, IE 11+, and the evergreen Chrome, Firefox, and Edge.
![Browsers Support](./assets/browsers-support.png)
[→ polyfills](https://github.com/webcomponents/webcomponentsjs)
## Links
- [westore](https://github.com/dntzhang/westore)
- [omijs.org](http://omijs.org/)
## License
MIT © Tencent
Please contact me[@dntzhang](https://github.com/dntzhang) for any questions.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,48 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
<meta charset="UTF-8" />
<title>Add Omi in One Minute</title>
</head>
<body>
<script src="https://unpkg.com/omi"></script>
<script>
const { WeElement, h, render, define } = Omi
class LikeButton extends WeElement {
install() {
this.data = { liked: false }
}
render() {
if (this.data.liked) {
return 'You liked this.'
}
return h(
'button',
{
onClick: () => {
this.data.liked = true
this.update()
}
},
'Like'
)
}
}
define('like-button', LikeButton)
render(h('like-button'), 'body')
</script>
<a href="https://github.com/Tencent/omi" target="_blank" style="position: fixed; right: 0; top: 0; z-index: 3;">
<img src="//alloyteam.github.io/github.png" alt="">
</a>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,214 +0,0 @@
[English](./main-concepts.md) | 简体中文
## Omi 文档
- [My First Element](#my-first-element)
- [Props](#props)
- [Event](#event)
- [Custom Event](#custom-event)
- [Ref](#ref)
- [Store](#store)
### My First Element
```js
import { WeElement, tag, render } from 'omi'
@tag('my-first-element')
class MyFirstElement extends WeElement {
render() {
return (
<h1>Hello, world!</h1>
)
}
}
render(<my-first-element></my-first-element>, 'body')
```
在 HTML 开发者工具里看看渲染得到的结构:
![fe](../assets/first-element.jpg)
除了渲染到 body你可以在其他任意自定义元素中使用 `my-first-element`
### Props
```js
import { WeElement, tag, render } from 'omi'
@tag('my-first-element')
class MyFirstElement extends WeElement {
render(props) {
return (
<h1>Hello, {props.name}!</h1>
)
}
}
render(<my-first-element name="world"></my-first-element>, 'body')
```
你也可以传任意类型的数据给 props:
```js
import { WeElement, tag, render } from 'omi'
@tag('my-first-element')
class MyFirstElement extends WeElement {
render(props) {
return (
<h1>Hello, {props.myObj.name}!</h1>
)
}
}
render(<my-first-element my-obj={{ name: 'world' }}></my-first-element>, 'body')
```
`my-obj` 将映射到 myObj驼峰的方式。
### Event
```js
class MyFirstElement extends WeElement {
onClick = (evt) => {
alert('Hello Omi!')
}
render() {
return (
<h1 onClick={this.onClick}>Hello, wrold!</h1>
)
}
}
```
### Custom Event
```js
@tag('my-first-element')
class MyFirstElement extends WeElement {
onClick = (evt) => {
this.fire('myevent', { name: 'abc' })
}
render(props) {
return (
<h1 onClick={this.onClick}>Hello, world!</h1>
)
}
}
render(<my-first-element onMyEvent={(evt) => { alert(evt.detail.name) }}></my-first-element>, 'body')
```
通过 `this.fire` 触发自定义事件fire 第一个参数是事件名称,第二个参数是传递的数据。通过 `evt.detail` 可以获取到传递的数据。
### Ref
```js
@tag('my-first-element')
class MyFirstElement extends WeElement {
onClick = (evt) => {
console.log(this.h1)
}
render(props) {
return (
<div>
<h1 ref={e => { this.h1 = e }} onClick={this.onClick}>Hello, world!</h1>
</div>
)
}
}
render(<my-first-element></my-first-element>, 'body')
```
在元素上添加 `ref={e => { this.anyNameYouWant = e }}` ,然后你就可以 JS 代码里使用 `this.anyNameYouWant` 访问该元素。
### Store
```js
import { WeElement, tag, render } from 'omi'
@tag('my-first-element')
class MyFirstElement extends WeElement {
//You must declare data here for view updating
static get data() {
return { name: null }
}
onClick = () => {
//auto update the view
this.store.data.name = 'abc'
}
render(props, data) {
//data === this.store.data when using store stystem
return (
<h1 onClick={this.onClick}>Hello, {data.name}!</h1>
)
}
}
const store = {
data: { name: 'Omi' }
}
render(<my-first-element name="world"></my-first-element>, 'body', store)
```
当使用 store 体系是,`static get data` 就仅仅被用来声明依赖,举个例子:
```js
static get data() {
return {
a: null,
b: null,
c: { d: [] },
e: []
}
}
```
会被转换成:
```js
{
a: true,
b: true,
'c.d':true,
e: true
}
```
举例说明 Path 命中规则:
| Proxy Path | updatePath |是否更新|
| ------ | ------ |------ |
| abc | abc | 更新 |
| abc[1] | abc | 更新 |
| abc.a| abc | 更新 |
| abc| abc.a | 不更新 |
| abc| abc[1] | 不更新 |
| abc| abc[1].c | 不更新 |
| abc.b| abc.b | 更新 |
以上只要命中一个条件就可以进行更新!
总结就是只要等于 updatePath 或者在 updatePath 子节点下都进行更新!
看可以看到 store 体系是中心化的体系?那么怎么做到部分组件去中心化?使用 tag 的第二个参数:
```js
@tag('my-first-element', true)
```
纯元素!不会注入 store!

View File

@ -1,225 +0,0 @@
English | [简体中文](./main-concepts.cn.md)
## Omi Docs
- [My First Element](#my-first-element)
- [Props](#props)
- [Event](#event)
- [Custom Event](#custom-event)
- [Ref](#ref)
- [Store](#store)
### My First Element
```js
import { WeElement, tag, render } from 'omi'
@tag('my-first-element')
class MyFirstElement extends WeElement {
render() {
return (
<h1>Hello, world!</h1>
)
}
}
render(<my-first-element></my-first-element>, 'body')
```
Look at the rendering structure in the HTML developer tool:
![fe](../assets/first-element.jpg)
You can also use `my-first-element` in any other custom element. Such as:
```js
import { WeElement, tag, render } from 'omi'
import './my-first-element'
@tag('other-element')
class OtherElement extends WeElement {
render() {
return (
<div>
<my-first-element></my-first-element>
</div>
)
}
}
```
### Props
```js
import { WeElement, tag, render } from 'omi'
@tag('my-first-element')
class MyFirstElement extends WeElement {
render(props) {
return (
<h1>Hello, {props.name}!</h1>
)
}
}
render(<my-first-element name="world"></my-first-element>, 'body')
```
You can also transmit any type of data to props:
```js
import { WeElement, tag, render } from 'omi'
@tag('my-first-element')
class MyFirstElement extends WeElement {
render(props) {
return (
<h1>Hello, {props.myObj.name}!</h1>
)
}
}
render(<my-first-element my-obj={{ name: 'world' }}></my-first-element>, 'body')
```
The `my-obj` will map to myObj with camel-case.
### Event
```js
class MyFirstElement extends WeElement {
onClick = (evt) => {
alert('Hello Omi!')
}
render() {
return (
<h1 onClick={this.onClick}>Hello, wrold!</h1>
)
}
}
```
### Custom Event
```js
@tag('my-first-element')
class MyFirstElement extends WeElement {
onClick = (evt) => {
this.fire('myevent', { name: 'abc' })
}
render(props) {
return (
<h1 onClick={this.onClick}>Hello, world!</h1>
)
}
}
render(<my-first-element onMyEvent={(evt) => { alert(evt.detail.name) }}></my-first-element>, 'body')
```
Tirgger custom event by `this.fire` and get the data by `evt.detail`.
### Ref
```js
@tag('my-first-element')
class MyFirstElement extends WeElement {
onClick = (evt) => {
console.log(this.h1)
}
render(props) {
return (
<div>
<h1 ref={e => { this.h1 = e }} onClick={this.onClick}>Hello, world!</h1>
</div>
)
}
}
render(<my-first-element></my-first-element>, 'body')
```
Add `ref={e => { this.anyNameYouWant = e }}` to attrs of the element, then you can get it by `this.anyNameYouWant`.
### Store
```js
import { WeElement, tag, render } from 'omi'
@tag('my-first-element')
class MyFirstElement extends WeElement {
//You must declare data here for view updating
static get data() {
return { name: null }
}
onClick = () => {
//auto update the view
this.store.data.name = 'abc'
}
render(props, data) {
//data === this.store.data when using store stystem
return (
<h1 onClick={this.onClick}>Hello, {data.name}!</h1>
)
}
}
const store = {
data: { name: 'Omi' }
}
render(<my-first-element name="world"></my-first-element>, 'body', store)
```
The staitc data will be transform to path for partial view updating, for example:
```js
static get data() {
return {
a: null,
b: null,
c: { d: [] },
e: []
}
}
```
Transformed path
```js
{
a: true,
b: true,
'c.d':true,
e: true
}
```
Exemplify the Path hit rule:
| proxy path | updatePath |Update|
| ------ | ------ |------ |
| abc | abc | true |
| abc[1] | abc | true |
| abc.a| abc | true |
| abc| abc.a | false |
| abc| abc[1] | false |
| abc| abc[1].c | false |
| abc.b| abc.b | true |
If you hit one condition above, you can update it.
Summary is as long as updatePath or updatePath sub nodes are updated.
Can we see that the store system is a centralization system? So how do we centralization of some components? Use the second parameters of tag:
```js
@tag('my-first-element', true)
```
Pure element! Store will not be injected!