Skip to content

Repository files navigation

MiniWex

Минималистичный реактивный фреймворк без зависимостей и chaining. CDN-ready.

🚀 Особенности

  • Без зависимостей — чистый JavaScript, никаких jQuery, scopex, ts-fns
  • Без chaining — явные вызовы методов, проще отладка
  • Реактивность — Proxy-based state management
  • Батчинг обновлений — throttle 16ms + requestAnimationFrame
  • Директивы — w-for, w-if, w-show, w-bind, w-model, w-text, w-html, w-on, w-route, w-navigate, w-ref, w-class, w-static
  • Хуки жизненного цикла — $mount, $update, $unmount, $change, $wiring
  • AJAX модуль — Promise-based $wire (get, post, put, delete)
  • Маршрутизация — встроенный router с поддержкой параметров
  • Сохранение состояния — localStorage персистентность
  • Утилиты — debounce, throttle, nextTick
  • CDN-ready — UMD сборка для подключения через <script>

🎯 Быстрый старт

<divid="app"><p>Счётчик: {{ count }}</p><button@click="increment">+</button></div><scriptsrc="miniwex.js"></script><script>constapp=MiniWex.createApp('#app',{count: 0},{methods: {increment: (e,state)=>{state.count++}}})app.mount()</script>

📖 Документация

Создание приложения

constapp=MiniWex.createApp(selector,initialState,options)

Параметры:

  • selector — CSS-селектор корневого элемента
  • initialState — начальное состояние (объект)
  • options — конфигурация:
    • methods — методы компонента
    • computed — вычисляемые свойства
    • hooks — хуки жизненного цикла
    • storage — ключ для localStorage персистентности

Реактивное состояние

constapp=MiniWex.createApp('#app',{count: 0,user: {name: 'John',age: 30}},{computed: {doubleCount: (state)=>state.count*2,isAdult: (state)=>state.user.age>=18}})

Изменения состояния автоматически обновляют DOM с батчингом (throttle 16ms).

Директивы

Текстовая интерполяция

<p>{{ message }}</p><p>{{ user.name }} - {{ user.age }} лет</p>

w-for — цикл

<ul><liw-for="item in items">
{{ item.name }} ({{ index }})
</li></ul>

w-if / w-show — условный рендеринг

<divw-if="isLoggedIn">Привет, {{ user.name }}!</div><divw-show="hasNotifications">🔔 {{ notificationCount }}</div>

w-bind — привязка атрибутов

<imgw-bind:src:imageUrlalt="Photo"><aw-bind:href:linkUrl>Click me</a><inputw-bind:value:inputValue>

w-model — двустороннее связывание

<inputtype="text" w-model="username"><inputtype="checkbox" w-model="isChecked"><inputtype="radio" w-model="selectedOption" value="opt1">

@event — обработчики событий

<button@click="handleClick">Click</button><input@input="handleInput"><form@submit="handleSubmit">

w-class — условные классы

<divw-class:active:isActive">Active item</div><buttonw-class:disabled:isDisabled">Submit</button>

w-route / w-navigate — навигация

<ahref="/about" w-route>О нас</a><buttonw-navigate:click:/contact>Контакты</button>

w-ref — ссылки на элементы

<inputw-ref:myInput>

Доступ через app.refs.myInput

w-text / w-html — контент

<divw-text="message"></div><divw-html="htmlContent"></div>

w-static — оптимизация производительности

Помечает блок как статический. Фреймворк не будет отслеживать изменения внутри этого элемента и его потомков. Используйте для крупного неизменяемого контента (статьи, футеры, иконки), чтобы ускорить работу приложения.

<articlew-static><h1>Заголовок статьи</h1><p>Этот текст никогда не изменится и не будет перерисовываться.</p><p>Выражения {{ count }} внутри работать НЕ будут.</p></article>

Важно: Внутри элементов с w-static реактивность отключена полностью. Интерполяция {{ }} и другие директивы на потомках игнорируются.

Методы

constapp=MiniWex.createApp('#app',{count: 0},{methods: {// Базовый методincrement: (e,state)=>{state.count++},// Метод с доступом к приложениюloadData: async(e,state,app)=>{constdata=awaitapp.$wire.get('/api/data')state.items=data},// Метод с параметрами из событияremoveItem: (e,state)=>{constid=e.target.dataset.idstate.items=state.items.filter(item=>item.id!==id)}}})

Хуки жизненного цикла

constapp=MiniWex.createApp('#app',{count: 0},{hooks: {// Вызывается после монтирования$mount: ({ state, refs })=>{console.log('App mounted',state)},// Вызывается после обновления DOM$update: ({ keys, state })=>{console.log('Updated keys:',keys)},// Вызывается при изменении состояния$change: ({ key, oldValue, newValue, state })=>{console.log(`${key}: ${oldValue}${newValue}`)},// Вызывается перед удалением$unmount: ({ state })=>{console.log('App unmounted')},// Вызывается при AJAX запросах$wiring: ({ url, method, data })=>{console.log('API call:',method,url)}}})

AJAX модуль ($wire)

// GET запросconstdata=awaitapp.$wire.get('/api/users')// POST запросconstnewUser=awaitapp.$wire.post('/api/users',{name: 'John',email: 'john@example.com'})// PUT запросawaitapp.$wire.put('/api/users/1',{name: 'John Updated'})// DELETE запросawaitapp.$wire.delete('/api/users/1')// С опциямиconstdata=awaitapp.$wire.get('/api/data',{headers: {'Authorization': 'Bearer token'}})

Маршрутизация

constapp=MiniWex.createApp('#app',{currentRoute: '/',page: 'home'},{hooks: {$mount: ({ state },app)=>{// Регистрация маршрутовapp.route('/',()=>{state.page='home'state.currentRoute='/'})app.route('/about',()=>{state.page='about'state.currentRoute='/about'})app.route('/user/:id',(path,params)=>{state.page='user'state.userId=params.id})// Навигацияapp.navigate('/about')// Получение текущего маршрутаconstcurrent=app.router.getCurrentRoute()}}})

Сохранение состояния (localStorage)

constapp=MiniWex.createApp('#app',{settings: {theme: 'light',lang: 'ru'}},{storage: 'myAppSettings'// Ключ в localStorage})app.mount()// Ручное сохранениеapp.persist('myAppSettings')

Утилиты

// DebounceconstdebouncedSearch=MiniWex.debounce((query)=>{console.log('Search:',query)},300)// ThrottleconstthrottledScroll=MiniWex.throttle(()=>{console.log('Scroll position:',window.scrollY)},100)// Next tickMiniWex.nextTick(()=>{console.log('DOM updated')})// Другие утилитыMiniWex.utils.deepClone(obj)MiniWex.utils.isObject(val)MiniWex.utils.generateUid('prefix')

🔧 API приложения

МетодОписание
app.mount()Монтирует приложение
app.unmount()Удаляет приложение
app.navigate(path)Переход по маршруту
app.route(path, handler)Регистрация маршрута
app.persist(key)Сохранение в localStorage
app.nextTick(fn)Выполнение после обновления DOM
app.component(name, config)Регистрация компонента

📊 Сравнение с оригинальным Wex

ВозможностьWexMiniWex
ЗависимостиjQuery, scopex, ts-fnsНет
Chaining
РеактивностьProxyProxy
Батчинг✅ (throttle 16ms)
Директивы12+12
Хуки
AJAX✅ (chaining)✅ (Promise)
Роутер
localStorage
Размер~50KB+~10KB
CDN

📝 Примеры

Смотрите examples.html для полноценных примеров:

  • Счётчик
  • TODO список
  • Загрузка API данных
  • Маршрутизация

📄 Лицензия

GPLv3

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages