6.2 KiB
English | 简体中文
Omi Docs
My First Element
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:
You can also use my-first-element
in any other custom element. Such as:
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
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:
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
class MyFirstElement extends WeElement {
onClick = (evt) => {
alert('Hello Omi!')
}
render() {
return (
<h1 onClick={this.onClick}>Hello, world!</h1>
)
}
}
Custom Event
@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')
Trigger custom event by this.fire
and get the data by evt.detail
.
CSS
@tag('my-first-element')
class MyFirstElement extends WeElement {
css() {
return `h1 { color: red; }`
}
render(props) {
return (
<h1>Hello, world!</h1>
)
}
}
render(<my-first-element onMyEvent={(evt) => { alert(evt.detail.name) }}></my-first-element>, 'body')
You can also dynamically generate the CSS:
css() {
return `h1 { color: ${Math.random() > 0.5 ? "red" : "blue"}; }`
}
You can also write CSS, less and sass separately to another file using to-string-loader of webpack:
{
test: /[\\|\/]_[\S]*\.scss$/,
use: [
'to-string-loader',
'css-loader',
'sass-loader'
]
}
Then:
import { tag, WeElement } from 'omi'
import style from '../style/_button.scss'
@tag('el-button', true)
class ElButton extends WeElement {
css() {
return style
}
...
...
Ref
@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
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 system
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 static data will be transform to path for partial view updating, for example:
static get data() {
return {
a: null,
b: null,
c: { d: [] },
e: []
}
}
Transformed path:
{
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:
@tag('my-first-element', true)
Pure element! Store will not be injected!
Slot
The HTML <slot>
element—part of the Web Components technology suite—is a placeholder inside a web component that you can fill with your own markup, which lets you create separate DOM trees and present them together.
import { tag, render, WeElement } from '../../src/omi'
@tag('hello-element')
class HelloElement extends WeElement {
render() {
return (
<div onClick={this.onClick}>
<p><slot name="my-text">My default text</slot></p>
</div>
)
}
}
@tag('my-app')
class MyApp extends WeElement {
render() {
return (
<div >
<hello-element>
<span slot="my-text">Let's have some different text!</span>
</hello-element>
</div>
)
}
}
render(<my-app></my-app>, 'body')
SSR
Recommended class libraries: