Coder Social home page Coder Social logo

havefive / omi Goto Github PK

View Code? Open in Web Editor NEW

This project forked from tencent/omi

0.0 2.0 0.0 26.76 MB

Open and modern framework for building user interfaces - 开放现代的Web组件化框架

Home Page: http://omijs.org

License: Other

JavaScript 87.84% HTML 7.50% CSS 1.47% TypeScript 3.19%

omi's Introduction

English | 简体中文 | 한국어

Omi v5.0.23

Omio v1.3.7

omi

Omi - Next generation web framework using web components with omio fallback(IE8+) in tiny js.

Why Omi?

  • Tiny size
  • Supports TypeScript
  • Reactive data-binding
  • Having official UI components - omiu
  • Excellent compatibility(IE8+) with omio
  • Real MVVM with mappingjs strong support
  • Enhanced CSS, rpx unit support base on 750 screen width
  • Compliance with browser trend and API design
  • Merge Web Components and JSX 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 and it's turing complete(template engine is not, es template string is but grammatical noise is too loud)
  • Look at Facebook React vs Web Components,Omi combines their advantages and gives developers the freedom to choose the way they like
  • Shadow DOM merges with Virtual DOM, Omi uses both virtual DOM and real Shadow DOM to make view updates more accurate and faster
  • 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:

Omi React
Omi React

Omi uses Shadow DOM based style isolation and semantic structure.

Ecosystem of Omi

Project Description
omi-docs Omi official documents
omio Omi for old browsers(IE8+ and mobile browsers).
omiu Omi official UI
omix Tiny size mini programe framework.
omi-chart Simple HTML5 Charts using chart-x tag.
md2site Static Site Generator with markdown powered by Omio.
omi-mvvm MVVM comes back bravely with mappingjs strong support.
omi-html Using htm in omi.
omi-30-seconds Useful Omi snippets that you can understand in 30 seconds.
omi-canvas Perfect fusion of web components, jsx and canvas.
omi-mp Develop and generate Web HTML5 Single-Page Applications by wechat mini program. The output source is base on omi + omi-router
omi-router Omi official router in 1KB js. → DEMO
omi-devtools Browser DevTools extension
omi-cli Project scaffolding
omi-ex Omi.js extension(TypeScript)
omi-transform Omi / css3transform integration. Made css3 transform super easy in your Omi project.
omi-tap Native tap event support(omi v4.0.24+)
omi-finger Support touch and gesture events in your Omi project.
omi-touch Smooth scrolling, rotation, pull to refresh and any motion for the web.
omi-use React hooks like API
omi-native Render web components to native
omi-i18n Internationalization solution for omi.js using i18next ecosystem
omi-page Tiny client-side router by page

Useful Resources

Title Name Other language Related
Styling We Components Using A Shared Style Sheet
Developer Tools support for Web Components in Firefox 63
Develop W3C Web Components with WebAssembly
60FPS Animation In Omi 简体中文 한국어
Render Web Components To Native 简体中文 한국어
Shadow Dom In Depth 简体中文
Part Theme Explainer 求翻译
Web Components MDN 简体中文
Web Components Google
Web Components Org
Web Components: the Right Way
Proxy MDN 简体中文 한국어
CSS Variables 简体中文 한국어
CSS Shadow Parts
Platform HTML5
Using requestIdleCallback 简体中文 A polyfill
The Power Of Web Components 简体中文
ShadowRoot 简体中文

Overview of the Readme

Add Omi in One Minute

This page demonstrates using Omi with no build tooling.

<!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

    define('like-button', class 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'
          )
        }
      })

    render(h('like-button'), 'body')
  </script>
</body>

</html>

You can also use like-button tag directly in HTML:

<body>
  <like-button />
</body>

Add Omi in 30 Seconds

You can also quickly build omi projects using modern JS code:

import { render, WeElement, define } from 'omi'

define('my-counter', class extends WeElement {
    static observe = true
    
    data = {
      count: 1
    }

    css () {
      return `span{
        color: red;
      }`
    }

    sub = () => {
      this.data.count--
    }

    add = () => {
      this.data.count++
    }

    render() {
      return (
        <div>
          <button onClick={this.sub}>-</button>
          <span>{this.data.count}</span>
          <button onClick={this.add}>+</button>
        </div>
      )
    }
  })

render(<my-counter />, 'body')

You can also update the view manually then you can choose the best time to update.

import { render, WeElement, define } from 'omi'

define('my-counter', class extends WeElement {
  count = 1

  //You can also pass strings directly
  css = `span{
        color: red;
      }`

  sub = () => {
    this.count--
    this.update()
  }

  add = () => {
    this.count++
    this.update()
  }

  render() {
    return (
      <div>
        <button onClick={this.sub}>-</button>
        <span>{this.count}</span>
        <button onClick={this.add}>+</button>
      </div>
    )
  }
})

render(<my-counter />, 'body')

→ counter demo

Getting Started

Install

$ npm i omi-cli -g               # install cli
$ omi init my-app     # init project, you can also exec 'omi init' in an empty folder
$ cd my-app           # please ignore this command if you executed 'omi init' in an empty folder
$ npm start                      # develop
$ npm run build                  # release

npx omi-cli init my-app is also supported(npm v5.2.0+).

Directory description:

├─ config
├─ public
├─ scripts
├─ src
│  ├─ assets
│  ├─ elements    //Store all custom elements
│  ├─ store       //Store all this store of pages
│  ├─ admin.js    //Entry js of compiler,will build to admin.html
│  └─ index.js    //Entry js of compiler,will build to index.html

Scripts

"scripts": {
    "start": "node scripts/start.js",
    "build": "PUBLIC_URL=. node scripts/build.js",
    "build-windows": "set PUBLIC_URL=.&& node scripts/build.js",
    "fix": "eslint src --fix"
}

You can set up the PUBLIC_URL, such as:

...
"build": "PUBLIC_URL=https://fe.wxpay.oa.com/dv node scripts/build.js",
"build-windows": "set PUBLIC_URL=https://fe.wxpay.oa.com/dv&& node scripts/build.js",
...

Switch omi and omio

Add or remove the alias config in package.json to switch omi and omio:

 ...
 "alias": {
    "omi": "omio"
  }
  ...

Project Template

Template Type Command Describe
Base Template(v3.3.0+) omi init my-app Basic omi or omio(IE8+) project template.
Base Template with snapshoot omi init-snap my-app Basic omi or omio(IE8+) project template with snapshoot prerendering.
TypeScript Template(omi-cli v3.3.0+) omi init-ts my-app Basic template with typescript.
Mobile Template omi init-weui my-app Mobile web app template with weui and omi-router.
omi-mp Template(omi-cli v3.0.13+) omi init-mp my-app Developing web with mini program template.
MVVM Template(omi-cli v3.0.22+) omi init-mvvm my-app MVVM template.

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

Hello Element

Define a custom element by extending WeElement base class:

import { define, WeElement } from 'omi'

define('hello-element', class extends WeElement {
  onClick = evt => {
    // trigger CustomEvent
    this.fire('abc', { name: 'dntzhang', age: 12 })
    evt.stopPropagation()
  }

 css = `
      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:

import { define, render, WeElement } from 'omi'
import './hello-element'

define('my-app', class extends WeElement {
  data = { abc: 'abc', passToChild: 123 }

  // define CustomEvent Handler
  onAbc = evt => {
    // get evt data by evt.detail
    this.data.abc = ' by ' + evt.detail.name
    this.data.passToChild = 1234
    this.update()
  }

  css = `
      div{
          color: green;
      }`
  }

  render(props, data) {
    return (
      <div>
        Hello {props.name} {data.abc}
        <hello-element
          onAbc={this.onAbc}
          propFromParent={data.passToChild}
          msg="WeElement"
        />
      </div>
    )
  }
})

render(<my-app name="Omi v4.0" />, 'body')

Tell Babel to transform JSX into Omi.h() call:

{
  "presets": ["env", "omi"]
}

The following two NPM packages need to be installed to support the above configuration:

"babel-preset-env": "^1.6.0",
"babel-preset-omi": "^0.1.1",

If you use babel7, you can also use the following packages and configuration:

npm install --save-dev @babel/preset-env
npm install --save-dev @babel/preset-react
{
  "presets": [
    "@babel/preset-env",
    [
      "@babel/preset-react",
      {
        "pragma": "Omi.h"
      }
    ]
  ]
}

If you don't want to write CSS in JS, you can use to-string-loader of webpack, For example, the following configuration:

{
  test: /[\\|\/]_[\S]*\.css$/,
  use: [
    'to-string-loader',
    'css-loader'
  ]
}

If your CSS file starts with "_", CSS will use to-string-loader., such as:

import { tag, WeElement render } from 'omi'

define('my-app', class extends WeElement {

  css = require('./_index.css')
  ...
  ...
  ...

You can also forget the tedious configuration and use omi-cli directly, no need to configure anything.

TodoApp

Here is a relatively complete example of TodoApp:

import { define, render, WeElement } from 'omi'

define('todo-list', function(props) {
  return (
    <ul>
      {props.items.map(item => (
        <li key={item.id}>{item.text}</li>
      ))}
    </ul>
  )
})

define('todo-app', class extends WeElement {
  static observe = true

  data = { 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 />, 'body')

Store

Omi Store provides a way to pass data through the component tree without having to pass props down manually at every level, injected from the root component and shared across all subcomponents. It's very simple to use:

import { define, render, WeElement } from 'omi'

define('my-hello', class extends WeElement {
  render() {
    //use this.store in any method of any children components
    return <div>{this.store.name}</div>
  }
})

define('my-app', class extends WeElement {
  handleClick = () => {
     //use this.store in any method of any children components
    this.store.reverse()
    this.update()
  }

  render() {
    return (
      <div>
        <my-hello />
        <button onclick={this.handleClick}>reverse</button>
      </div>
    )
  }
})

const store = {
  name: 'abc',
  reverse: function() {
    this.name = this.name.split("").reverse().join("")
  }
}
//Injection through a third parameter
render(<my-app />, document.body, store)

Unlike global variables, when there are multiple root nodes, multiple stores can be injected, while there is only one global variable.

Mitt

If you don't want to use store's data system, you can also use publish subscribe mode. For example, using mitt across component communication in Omi:

Observe

Omi Observe

You can also use observe to create response views for element who no need store, such as:

import { define, WeElement } from "omi"

define("my-app", class extends WeElement {
  static observe = true

  install() {
    this.data.name = "omi"
  }

  onClick = () => {
    this.data.name = "Omi V4.0"
  }

  render(props, data) {
    return (
      <div onClick={this.onClick}>
        <h1>Welcome to {data.name}</h1>
      </div>
    )
  }
})

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 update
updated after update
beforeRender before render()
receiveProps parent element re-render will trigger it

Debugging

Easy to debug via Omi DevTools Extension [Install from Chrome WebStore], using Omi DevTools you can simply debug and manage your UI without any configuration. Just install and debug.

Since Omi uses Web Components and Shadow-DOM, it doesn't need to have another elements panel such as React has. It just adds a panel to the Elements' sidebar and it's powerful as much as React DevTools.

Omi DevTools

React to Omi

For example, the below is about migration React button as weui Omi button:

react to omi

Browsers Support

Omio - Omi for old browsers(IE8+ and mobile browsers)

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

→ Polyfills

<script src="https://unpkg.com/@webcomponents/[email protected]/webcomponents-bundle.js"></script>

Contributors

Maintainers

Please contact us for any questions. Also, Add Omi QQ Group.

Thanks

License

MIT © Tencent

omi's People

Contributors

dntzhang avatar 1921622004 avatar xcatliu avatar f avatar yanceyou avatar pasturn avatar akira-cn avatar yisar avatar xcodebuild avatar daizhan avatar elfman avatar havefive avatar guisturdy avatar eyea avatar nobey avatar wozhuang avatar jayzou avatar zhangsanshi avatar winstonxie avatar yolio2003 avatar ritschwumm avatar xland avatar ilker0 avatar howel52 avatar nanhupatar avatar electerious avatar tagir-a avatar web-padawan avatar nbompetsis avatar mrgrabazu avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.