| Английский | Русский |
import { render, signal, tag, Component, h } from 'omi'
const count = signal(0)
function add() {
count.value++
}
function sub() {
count.value--
}
@tag('counter-demo')
export class CounterDemo extends Component {
static css = 'span { color: red; }'
render() {
return (
<>
<button onClick={sub}>-</button>
<span>{count.value}</span>
<button onClick={add}>+</button>
</>
)
}
}
Использование этого компонента:
import { h } from 'omi'
import './counter-demo'
render(<counter-demo />, document.body)
// или
import { CounterDemo, Other } from './counter-demo'
// Предотвратите удаление других импортов при сборке проекта
render(<CounterDemo />, document.body)
// или
document.body.appendChild(document.createElement('counter-demo'))
```## Установка
```bash
npm i omi
Для быстрой установки проекта с использованием Omi + Vite + TS/JS:
$ npx omi-cli init my-app # или создайте проект на JS командой: npx omi-cli init-js my-app
$ cd my-app
$ npm start # запустить разработку
$ npm run build # собрать проект
Для быстрой установки проекта с использованием Omi + маршрутизации + сигнализации + отложенных запросов + Tailwindcss + Vite + TS:```bash
$ npx omi-cli init-spa my-app
$ cd my-app
$ npm start # запустить разработку
$ npm run build # собрать проект
### Пакеты — Основные пакеты
- [`omi`](https://github.com/Tencent/omi/tree/master/packages/omi) — Реализация фреймворка omi.
- [`omi-form`](https://github.com/Tencent/omi/tree/master/packages/omi-form) — Мощное, простое и кросс-фреймворков решение для форм.
- [`lucide-omi`](https://github.com/omijs/lucide-omi) — Коллекция значков Lucide для omi.
- [`omiu`](https://github.com/Tencent/omi/tree/master/packages/omiu) — Направлено на создание лучших веб-компонентов. Например, мощный [vchart](https://visactor.io/vchart) и [vtable](https://visactor.io/vtable).
- [`omi-router`](https://github.com/Tencent/omi/tree/master/packages/omi-router) — Создание одностраничных приложений (SPA) с использованием фреймворка omi.
- [`omi-cli`](https://github.com/omijs/cli) — Быстрая настройка проекта Omi + Vite + TS/JS.
- Наборы для старта (не опубликованы в npm)
- [`omi-elements`](https://github.com/Tencent/omi/tree/master/packages/omi-elements) — Кит UI Omi с элементами Tailwind.
- [`omi-starter-spa`](https://github.com/Tencent/omi/tree/master/packages/omi-starter-spa) — Начальный репозиторий для создания одностраничных приложений с использованием Omi + OmiRouter + Tailwindcss + TypeScript + Vite + Prettier.
- [`omi-starter-ts`](https://github.com/Tencent/omi/tree/master/packages/omi-starter-ts) — Начальный репозиторий для создания веб-приложений или повторно используемых компонентов с использованием Omi на основе TypeScript и Vite.
- [`omi-starter-tailwind`](https://github.com/Tencent/omi/tree/master/packages/omi-starter-tailwind) — Начальный репозиторий для создания веб-приложений или повторно используемых компонентов с использованием Omi + Tailwindcss + TypeScript + Vite. - [`omi-starter-js`](https://github.com/Tencent/omi/tree/master/packages/omi-starter-js) - Начальный репозиторий для создания веб-приложений или повторно используемых компонентов с использованием Omi на основе JavaScript и Vite.
- [`omi-vue`](https://github.com/Tencent/omi/tree/master/packages/omi-vue) - Vue SFC + Vite + OMI + OMI-WeUI.
- Компоненты
- [`omi-weui`](https://github.com/Tencent/omi/tree/master/packages/omi-weui) - Компоненты WeUI для omi.
- [`omi-auto-animate`](https://github.com/Tencent/omi/tree/master/packages/omi-auto-animate) - Версия omi пакета @formkit/auto-animate.
- [`omi-suspense`](https://github.com/Tencent/omi/tree/master/packages/omi-suspense) - Обработка асинхронных зависимостей.
- Директивы
- [`omi-transition`](https://github.com/Tencent/omi/tree/master/packages/omi-transition) - Применение анимаций при входе и выходе компонента из DOM.
- [`omi-ripple`](https://github.com/Tencent/omi/tree/master/packages/omi-ripple) - Легковесный компонент для добавления эффекта нажатия на элементы пользовательского интерфейса.
- Примеры (не опубликованы в npm)
- [`snake-game-2tier`](https://github.com/Tencent/omi/tree/master/packages/snake-game-2tier) - Игра Snake с использованием класса `Signal`.
- [`snake-game-3tier`](https://github.com/Tencent/omi/tree/master/packages/snake-game-3tier) - Игра Snake с использованием реактивных функций.
- [`omi-tutorial`](https://github.com/omijs/tutorial) - Исходный код учебника по Omi.
**Если вы хотите помочь проекту расти, начните с простого распространения информации среди своих коллег!**- [Поделиться через Dev.to](<https://dev.to/new?prefill=%20---%0Atitle%3A%20Omi%20-%20Web%20Components%20Framework%0A----%20Домашняя%20страница%3A%20%5Bomijs.org%5D(%2Fomijs.org%2F)%20GitHub%3A%5Bhttps://github.com/Tencent/omi%5D(https://github.com/Tencent/omi)%0A-%20%F0%9F%93%B6%20**Сигнальное**%20реактивное%20программирование%0A-%20%F0%9F%8E%89%20%5BTailwind%20Element%20Omi%20UI%20Kit%5D(https://omi.cdn-go.cn/elements/latest/%2F)%0A-%20%E2%9A%A1%20**Малый**%20размер%2C%20**Быстрая**%20производительность%0A-%20%F0%9F%8C%90%20Все%20что%20вы%20нуждаетесь%3A%20**Web%20Components**%2C%20**JSX**%2C%20Router%2C%20Suspense%2C%20Directive%2C%20Tailwindcss.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%20.%url=http://omijs.org/&title=web%20components%20framework
- [Поделиться через ВКонтакте](https://vk.com/share.php?url=http://omijs.org/)
- [Поделиться через Weibo](https://service.weibo.com/share/share.php?url=https://omijs.org/&title=web%20components%20framework)
- [Поделиться через Hackernews](https://news.ycombinator.com/submitlink?u=http://omijs.org/&t=web%20components%20framework)
Спасибо!## Использование
### TodoApp с реактивными функциями
> Программирование ориентированное на данные
В программировании, ориентированном на данные, акцент делается на данных самих по себе и операциях над ними, а не на объектах или структурах данных, которые хранят эти данные. Этот подход к программированию акцентирует внимание на изменениях и потоках данных, а также на том, как реагировать на эти изменения. TodoApp с реактивными функциями является хорошим примером этого подхода, используя концепции реактивного программирования, где интерфейс пользователя автоматически обновляется в ответ на изменения данных (например, списка задач).
```tsx
import { render, signal, computed, tag, Component, h } from 'omi'
const todos = signal([
{ text: 'Узнать OMI', completed: true },
{ text: 'Узнать Web Components', completed: false },
{ text: 'Узнать JSX', completed: false },
{ text: 'Узнать Signal', completed: false }
])
const completedCount = computed(() => {
return todos.value.filter(todo => todo.completed).length
})
const newItem = signal('')
function addTodo() {
// api a
todos.value.push({ text: newItem.value, completed: false })
todos.update() // Вызвать автоматическое обновление интерфейса
// api b, аналогично api a
// todos.value = [...todos.value, { text: newItem.value, completed: false }]
newItem.value = '' // Изменение типа значения может вызвать автоматическое обновление интерфейса
}
function removeTodo(index: number) {
todos.value.splice(index, 1)
todos.update() // Вызвать автоматическое обновление интерфейса
}
```@tag('todo-list')
class TodoList extends Component {
onInput = (event: Event) => {
const target = event.target as HTMLInputElement;
newItem.value = target.value;
};
render() {
return (
<>
<input type="text" value={newItem.value} onInput={this.onInput} />;
<button onClick={addTodo}>Добавить</button>;
<ul>
{todos.value.map((todo, index) => {
return (
<li>
<label>
<input
type="checkbox"
checked={todo.completed}
onInput={() => {
todo.completed = !todo.completed;
todos.update(); // Вызвать автоматическое обновление интерфейса
}}
/>;
{todo.completed ? <s>{todo.text}</s> : todo.text};
</label>;
{' '}
<button onClick={() => removeTodo(index)}>❌</button>;
</li>
);
})};
</ul>;
<p>Количество выполненных задач: {completedCount.value}</p>;
</>
);
};
}
```рендер(<todo-list />, document.body);
vite.config.js:
import { defineConfig } from 'vite';
export default defineConfig({
esbuild: {
jsxInject: "import { h } from 'omi'",
jsxFactory: "h",
jsxFragment: "h.f"
}
});
Вы можете внедрять код во время сборки, чтобы не пришлось вручную экспортировать h
.
my-counter.tsx:
import { tag, Component, h, bind } from 'omi'
@tag('my-counter')
class MyCounter extends Component {
static props = {
count: {
type: Number,
default: 0,
changed(newValue, oldValue) {
this.state.count = newValue
this.update()
}
}
}
state = {
count: null
}
install() {
this.state.count = this.props.count
}
@bind
sub() {
this.state.count--
this.update()
this.fire('change', this.state.count)
}
@bind
add() {
this.state.count++
this.update()
this.fire('change', this.state.count)
}
render() {
return (
<>
<button onClick={this.sub}>-</button>
<span>{this.state.count}</span>
<button onClick={this.add}>+</button>
</>
)
}
}
<script setup>
import { ref } from 'vue'
// импортируем omi компонент
import './my-counter'
defineProps({
msg: String,
})
const count = ref(0)
const change = (e) => {
count.value = e.detail
}
</script>
<template>
<h1>{{ msg }}</h1>
<my-counter @change="change" :count="count" />
<p>
【Omi】
</p>
<div class="card">
<button type="button" @click="count++">count is {{ count }}</button>
<p>
【Vue】
</p>
</div>
</template>
Если вы fire
событие count-change
в компоненте Omi:
this.fire('count-change', this.state.count)
Чтобы использовать компонент и слушать события в Vue:
<my-counter @count-change="change" :count="count" />
import { useState, useRef, useEffect } from 'react';
import useEventListener from '@use-it/event-listener';
import './my-counter';
function App() {
const [count, setCount] = useState(100);
const myCounterRef = useRef(null);
useEffect(() => {
const counter = myCounterRef.current;
if (counter) {
const handleChange = (evt) => {
setCount(evt.detail);
};
counter.addEventListener('change', handleChange);
return () => {
counter.removeEventListener('change', handleChange);
};
}
}, []);
}
``````markdown
## Участники проекта
<a href="https://github.com/Tencent/omi/graphs/contributors">
<img src="./assets/contributors.png" />
</a>
## Лицензия
MIT © Tencent
return (
<>
<h1>Omi + React</h1>
<my-counter count={count} ref={myCounterRef}></my-counter>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
счет равен {count}
</button>
</div>
</>
);
}
export default App;
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )