Omiu - 使用 Omi 打造的跨框架、跨主题 UI 组件库。
使用 TypeScript 开发跨框架的按钮组件:
import { tag, WeElement, h, extractClass } from 'omi'
import * as css from './index.scss'
interface Props {
size?: 'medium' | 'small' | 'mini',
type?: 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'text'
plain?: boolean,
round?: boolean,
circle?: boolean,
loading?: boolean,
disabled?: boolean,
icon?: string,
autofocus?: boolean,
nativeType?: 'button' | 'submit' | 'reset',
block?: boolean
text?: string
}
@tag('o-button')
export default class Button extends WeElement<Props>{
static css = css
static defaultProps = {
plain: false,
round: false,
circle: false,
loading: false,
disabled: false,
autofocus: false,
nativeType: 'button',
block: false
}
static propTypes = {
size: String,
type: String,
plain: Boolean,
round: Boolean,
circle: Boolean,
loading: Boolean,
disabled: Boolean,
icon: String,
autofocus: Boolean,
nativeType: String,
block: Boolean,
text: String
}
render(props) {
return <button disabled={props.disabled} {...extractClass(props, 'o-button', {
['o-button-' + props.type]: props.type,
['o-button-' + props.size]: props.size,
'is-plain': props.plain,
'is-round': props.round,
'is-circle': props.circle,
'is-disabled': props.disabled,
'is-block': props.block
})} type={props.nativeType} >
{props.loading && <i class='icon-loading'></i>}
{props.text}
<slot></slot>
</button>
}
}
$ npm i omi-cli -g # install cli
$ omi init my-app # 初始化项目,也可以在空目录里执行 'omi init'
$ cd my-app # 如果在空目录里执行 'omi init' 忽略这条命令
$ npm start # 开发
$ npm run build # 编译发布
npx omi-cli init my-app 也支持(要求 npm v5.2.0+)
$ npm i omi-cli -g # install cli
$ omi init-component my-component # 初始化项目,也可以在空目录里执行 'omi init'
$ cd my-app # 如果在空目录里执行 'omi init' 忽略这条命令
$ npm start # 开发
$ npm run build # 编译发布
npx omi-cli init-component my-component 也支持(要求 npm v5.2.0+)
→ Omi 生态学习路线图( github /Tencent/omi/tree/master/assets/rm.md)
| 项目 | 描述 |
|---|---|
| omi-docs 和 例子 和 webcomponents.dev | Omi 官方文档 |
| omi-router | Omi 官方路由,超级小的尺寸,只有 1KB 的 js |
| omi-cli | 项目脚手架工具,各种模板任你选 → 基础模板 |
| CEE | custom-elements-everywhere 评分 |
| Project | Description |
|---|---|
| omi-snake | omi 写的 MVP 架构的贪吃蛇游戏 |
| omi-kbone-snake | omi-kbone 写的 MVP 架构的跨端贪吃蛇游戏,支持小程序和 H5 |
| Preact-snake & → Touch the demo | Preact + Preact-CSS + Omis 写的贪吃蛇 |
| [P]react-snake & → Touch the demo | react/preact 写的 MVP 架构的贪吃蛇游戏 |
| omix-snake | Omix 写的 MVP 架构贪吃蛇 |
| 项目 | 描述 |
|---|---|
| omi-piano | Omi 钢琴, 开始演奏吧! |
| omi-devtools | 谷歌浏览器开发工具扩展 |
| md2site | 用 markdown 生成静态网站文档. |
| omi-chart | 一个 chart-x 标签搞定报表 |
| omi-30-seconds | 30 秒理解一段有用的 Omi 代码片段. |
| omi-swiper | Omi + Swiper |
| omi-vscode | VSCode extension for omi, Install now! |
| omi-sprite | Web Components, JSX 和 Canvas 的完美融合 |
| omi-canvas | Web Components, JSX 和 Canvas 的完美融合 |
| omi-ex | Omi.js 扩展(TypeScript) |
| omi-transform | Omi 和 css3transform 完美结合. 让 css3 transform 在你的 Omi 项目中变得超级简单. |
| omi-finger | Omi 官方手势库 |
| omi-touch | 丝般顺滑的触摸运动 |
| omi-snap | 预渲染骨架屏 |
| omi-i18n | Omi 国际化解决方案 |
| omie | Omi.js 和 Electron.js 打造跨平台桌面应用 |
| Soo | 和 Omi 一样的 API,但是更小且没有 JSX, virtual DOM 和 store |
对比同样开发 TodoApp, Omi 和 React 渲染完的 DOM 结构,Omi 使用 Shadow/Light DOM 隔离样式和语义化结构:
| Omi | React |
|---|---|
![]() |
![]() |
import { h, WeElement, tag, classNames } from 'omi';
import * as styles from './_index.less';
interface ButtonProps {
href?: string,
disabled?: boolean,
type?: 'default' | 'primary' | 'danger',
htmltype?: 'submit' | 'button' | 'reset',
onClick?: (e: any) => void
}
const TAG = 'o-button'
declare global {
namespace JSX {
interface IntrinsicElements {
[TAG]: Omi.Props & ButtonProps
}
}
}
@tag(TAG)
export default class oButton extends WeElement<ButtonProps> {
...
| Template Type | Command | Describe |
|---|---|---|
| 基础模板(v3.3.0+) | omi init my-app | 基础模板,支持 omi 和 omio(IE8+) |
| Kbone Template | omi init-kbone my-app | 使用 omi 开发小程序或者 Web |
先创建一个自定义元素:
import { define, WeElement } from 'omi'
define('hello-element', class extends WeElement {
onClick = evt => {
// trigger CustomEvent
this.fire('Abc', { name: 'dntzhang', age: 12 })
evt.stopPropagation()
}
//如果需要在 html 里直接使用 <hello-element></hello-element>,必须声明 propTypes
static propTypes = {
msg: String
}
static css = `
div {
color: red;
cursor: pointer;
}`
render(props) {
return (
<div onClick={this.onClick}>
Hello {props.msg}
<div>Click Me!</div>
</div>
)
}
})
使用该元素:
import { define, render, WeElement } from 'omi'
import './hello-element'
define('my-app', class extends WeElement {
data = { abc: 'abc' }
// define CustomEvent Handler
onAbc = evt => {
// get evt data by evt.detail
this.data.abc = ' by ' + evt.detail.name
this.update()
}
static css = `
div{
color: green;
}`
render(props) {
return (
<div>
Hello {this.data.abc}
<hello-element
onAbc={this.onAbc}
msg="WeElement"
/>
</div>
)
}
})
render(<my-app name="Omi v4.0" />, 'body')
告诉 Babel 把 JSX 转化成 Omi.h() 的调用:
{
"presets": ["env", "omi"]
}
需要安装下面两个 npm 包支持上面的配置:
"babel-preset-env": "^1.6.0",
"babel-preset-omi": "^0.1.1",
如果你使用 babel7,也可以使用如下包和配置:
npm install --save-dev @babel/preset-env
npm install --save-dev @babel/preset-react
{
"presets": [
"@babel/preset-env",
[
"@babel/preset-react",
{
"pragma": "Omi.h",
"pragmaFrag": "Omi.h.f"
}
]
]
}
如果不想把 css 写在 js 里,你可以使用 webpack to-string-loader, 比如下面配置:
{
test: /[\\|\/]_[\S]*\.css$/,
use: [
'to-string-loader',
'css-loader'
]
}
如果你的 css 文件以 _ 开头, css 会使用 to-string-loader, 如:
import { tag, WeElement render } from 'omi'
define('my-app', class extends WeElement {
css = require('./_index.css')
...
...
...
你也可以忘掉这一对繁琐的配置直接使用 omi-cli,不需要你配置任何东西。
| 钩子方法 | 触发时机 |
|---|---|
| install | 初始化安装 |
| installed | 插入到文档之后且安装完成 |
| uninstall | 从文档中卸载移除 |
| beforeUpdate | update 之前 |
| updated | update 之后 |
| beforeRender | render() 之前 |
| receiveProps | 父组件更新时候触发, 返回 false 可以阻止更新 |
console.log(Omi.elements)
Omio( github /Tencent/omi/tree/master/packages/omio) - 兼容老浏览器的 Omi 版本(支持到 IE8+)
→ polyfills( github /webcomponents/webcomponentsjs)
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@2.0.0/webcomponents-bundle.js"></script>
项目地址: github /Tencent/omi

