Создайте компоненты пользовательского интерфейса с HTML, который у вас уже есть.
2 КБ GZIPPED и 6 КБ. ?
data в существующий HTML < div data-component =" Counter " >
< p data-bind =" state:Counter.count " > 0 </ p >
< button data-action =" click->Counter.decrement " >
-1
</ button >
< button data-action =" click->Counter.increment " >
+1
</ button >
</ div >class JavaScript? import { Component } from "domponent" ;
export default class Counter extends Component {
constructor ( el ) {
super ( el ) ;
}
increment ( ) {
this . setState ( { count : this . state . count + 1 } ) ;
}
decrement ( ) {
this . setState ( { count : this . state . count - 1 } ) ;
}
} import { Init } from "domponent" ;
import Counter from "./Counter.js" ;
const config = {
selector : document . getElementById ( "root" ) ,
components : {
Counter
} ,
appCreated : callbackFunction
} ;
new Init ( config ) ;И тебе нравится идти !!
Эта библиотека устанавливает чистый и современный способ превратить предварительный HTML в компоненты пользовательского интерфейса. Вы можете легко реализовать некоторые данные связывания данных, обрабатывать объем, передавать данные и создавать компоненты, используя некоторые из соглашений в этом сценарии. Это предназначено для того, чтобы быть очень очень легкой альтернативой стимулам с небольшим вкусом реагирования (методы жизненного цикла, реквизит и состояние компонентов).
Domponent не обрабатывает рендеринг на стороне клиента из коробки, не создает виртуальный DOM, не отличается DOM (хотя он выполняет состояние дифференцировки и реквизиты). Это не предназначено для обработки маршрутизации или всего состояния приложения. Он предназначен для принятия фрагментов HTML (Thymeleaf, Rails, Pug, любой шаблонный двигатель, который вы используете) и создать повторную функциональность в форме компонентов.
Domponent в некотором роде похож на нокаут:
В отличие от nockoutjs, domponent:
Нокаутировать
HTML
< p > First name: < input data-bind =" value: firstName " /> </ p >
< p > Last name: < input data-bind =" value: lastName " /> </ p >
< h2 > Hello, < span data-bind =" text: fullName " > </ span > ! </ h2 >Младший
var ViewModel = function ( first , last ) {
this . firstName = ko . observable ( first ) ;
this . lastName = ko . observable ( last ) ;
this . fullName = ko . pureComputed ( function ( ) {
return ` ${ this . firstName ( ) } ${ this . lastName ( ) } ` ;
} , this ) ;
} ;
ko . applyBindings ( new ViewModel ( "Planet" , "Earth" ) ) ;Domponent
HTML
< div data-component =" Hello " data-state =" { " firstName ": "Planet", "lastName": "Earth"}" >
< p > First name: < input data-action =" input->Hello.setFirstName " /> </ p >
< p > Last name: < input data-action =" input->Hello.setLastName " /> </ p >
< h2 > Hello, < span data-bind =" state:Hello.fullName " > </ span > ! </ h2 >
</ div >Младший
import { Component } from "domponent" ;
export default class Hello extends Component {
constructor ( conf ) {
super ( conf ) ;
}
setFirstName ( event ) {
this . setState ( { firstName : event . target . value } , ( ) => {
this . setFullName ( ) ;
} ) ;
}
setLastName ( event ) {
this . setState ( { lastName : event . target . value } , ( ) => {
this . setFullName ( ) ;
} ) ;
}
setFullName ( ) {
this . setState ( {
fullName : ` ${ this . state . firstName } ${ this . state . lastName } `
} ) ;
}
}https://tamb.github.io/domponent/
Список TODO: https://codesandbox.io/embed/domponent-todo-with-undo-redo-p3s2?fontsize=14
Местная демонстрация
git clone это репоnpm installnpm run build:html-dev или npm run build:html-prod npm install -- save domponent Вы можете использовать версию ES5, импортируя этот файл domponent/dist/domponent.es5.production.min.js
Если вы не используете транспориста, рекомендуется использовать ES5 UMD. Итак, вот ссылка на JSDELVR:
// production
< script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/domponent@VERSION/dist/domponent.es5.production.min.js" defer > </ script >
// development
< script type = "text/javascript" src = "https://cdn.jsdelivr.net/npm/domponent@VERSION/dist/domponent.es5.development.min.js" defer > < / script > Примечание. Используйте столько или мало этой библиотеки, сколько хотите. Вы можете использовать это только для атрибутов только data-component , data-ref и data-ref-array и значительно упрощает ваш выбор DOM. Вы можете сделать компоненты без сохранения состояния с классом Exponent . Небо - предел. По своей сути Domponent - это набор классов по утилитам для вашего HTML.
data-component Мы используем этого плохого мальчика, чтобы соответствовать имени компонента с соответствующим class в объекте конфигурации Init
Пример: если ваш html-это data-component="Counter" | У вас должен быть компонент в вашей конфигурации, называемой Counter
data-bind Привязывает state или props с textContent элемента сначала, который вы указываете, хотите ли вы связать state или props data-bind="state:Counter.count" или data-bind="props:Counter.count" левая половина : рассказывает компоненту, с каким объектом (состояние или рекви
data-actionПривязывает событие DOM с помощью метода компонентов. Рассмотрим следующее:
< button data-action =" click->Counter.increment " >
+1
</ button > Левая половина : представляет буквальную строку для события DOM для прослушивания. Правая половина соответствует методу компонента
Примечание: вы можете добавить несколько слушателей с помощью трубы | пример:
< button data-action =" click->Counter.increment|mouseover->Counter.anotherMethod " >
+1
</ button > Вы также можете передать варианты eventListener . Варианты должны быть после . После класса метод. Варианты должны быть разделены запятыми ,
< button
data-action =" click->Counter.increment.passive,capture|mouseover->Counter.anotherMethod.once,passive "
>
+1
</ button > data-state Если вы хотите создать создание своего компонента с помощью определенного состояния в памяти, вы должны прикрепить атрибут data-state к корневой элементу примера компонента:
<div data-component="Counter" data-state='{"count":24, "isEven": true}'>
...
</div>
Это верно. data-state принимает любой действительный объект JSON.
data-ref Если вам нужно ссылаться на элементы DOM, вы можете использовать data-ref , как SO:
< div data-ref =" Counter.myElement " > </ div > Вам нужно предварительно предварительно, какой компонент включен элемент. Затем он хранится в объекте компонентов $refs .
Затем вы можете получить доступ к Counter , используя this.$refs.myElement в экземпляре компонента.
data-ref-arrayВы можете создать множество элементов в своем компоненте таким образом:
< div data-ref-array =" Counter.elements " > </ div >
< div data-ref-array =" Counter.elements " > </ div > Затем он хранится в объекте компонентов $refs . Вы можете получить доступ к массиву элементов в своем компоненте с this.$refs.elements .
data-key Это совершенно необязательно. Это уникальная строка для каждого экземпляра компонента.
Это используется внутри, чтобы связать реквизит. Поэтому вы должны знать $key о компоненте, от которого вы получаете реквизит.
< div data-component =" Counter " data-key =" aUniqueKey " >
...
</ div >Допустим, вы зацикливаете это на своем языке шаблона. Вы должны убедиться, что ваши ключи уникальны.
# for (let i=0; i < 10 ; i++){
< div data-component =" Counter " key =" `aUniqueKey${i}` " > ... </ div >
} Если вы не используете этот атрибут, уникальный ключ будет автоматически назначен для каждого экземпляра компонента. Это можно получить через this.$key
data-props Вы можете поделиться состоянием из родительского компонента в качестве props в детском компоненте. Разметка будет выглядеть так
< div data-component =" Counter " key =" parentCounter " >
< div
data-props =" myAwesomeProp<-parentCounter:ofFive "
data-component =" DisplayAnything "
> </ div >
</ div > Левая сторона стрелки <- это имя опоры в компоненте DisplayAnything . Правая сторона стрелы - $key от родительского компонента, толстой кишки : и название части state , чтобы наследовать.
Затем вы можете использовать методы жизненного цикла propsWillUpdate и propsDidUpdate чтобы внести изменения в вашем дочернем компоненте.
Component ?Давайте продолжим с счетчиком. Минимальный JS, необходимый для создания компонента, ниже:
class Counter extends Component {
constructor ( conf ) {
super ( conf ) ;
}
} super добавляет базовые методы и свойства ваших потребностей компонента.
Не мутируйте государство напрямую. Назовите this.setState
setState ( stateObject , callbackFunction ) ;Это похоже на концепцию, чтобы React Setstate - хотя он реализован по -разному.
Вы можете добавить состояния по умолчанию в свой компонент JS и переопределить их в DOM
export default class Counter extends Component {
constructor ( conf ) {
super ( conf ) ;
this . state = {
count : parseInt ( this . state . count ) || 0 ,
isEven : this . state . count
? this . state . count % 2 === 0
? true
: false
: true ,
stateFieldFromDOM : this . state . stateFieldFromDOM || "default cat" ,
stateFieldDefault : "default iPhone 11"
} ;
this . setState ( this . state ) ;
} <div data-component="Counter" data-state="{"count": 4, "isEven":true, "stateFieldFromDOM": "some value here"}"
Приведенные выше поля состояния будут переоценить поля штата JS по умолчанию.
Привязка значения от setState всегда будет для textContent . Если вы хотите использовать состояние/реквизит для рендеринга HTML, вы можете добавить наблюдателя за это значение и обновить узел $refs , в котором будет размещен новый HTML.
watch ( ) {
return {
count : {
post ( newCount ) {
this . $refs . exclaimCount . innerHTML = `<div class="uppercase"> ${ newcount } !</div>` ;
}
}
}
}Ниже приведены методы, которые вы можете использовать для доступа к компонентам в различных точках их жизненного цикла
| Метод жизненного цикла | Контекст | Описание |
|---|---|---|
| соединение | Компонент/показатель | Прежде чем библиотека поднимает какой -либо из вашего компонента/экспонента, и у вас есть доступ к другим методам |
| подключенный | Компонент/показатель | После того, как ваш компонент/экспонент подключен и все EventListeners на месте |
| отключение | Компонент/показатель | Перед удалением eventlisteners и удаления компонента/экспонента из памяти |
| propswillupdate | Компонент/показатель | Перед тем, как реквизиты обновляются в вашем компоненте, мутации DOM не произошли |
| propsdidupdate | Компонент/показатель | После обновления реквизита и DOM изменился |
| Statewillupdate | Компонент | Перед тем, как изменилось состояние текущего компонента или любого из реквизита его иждивенцев |
| Заявленная | Компонент | Детские компоненты с унаследованными реквизитами сделали свои манипуляции с DOM, и состояние и реквизиты изменились |
Component и классы Exponent имеют метод watch , который должен вернуть объект. Наблюдатели позволяют вам подключаться к конкретному state или изменению значения props во время жизни компонента. Это позволяет изолировать логику вашей состояния вместо того, чтобы объединить все это с помощью stateWillUpdate , stateDidUpdate , propsWillUpdate или propsDidUpdate . Это предназначено для тщательного имитации наблюдателей в Vue.JS Примечание . Не назовите свое state и props одинаково. Это плохая практика и сломает наблюдателей.
watch ( ) {
return {
myField : {
pre ( newValue , oldValue ) {
// my logic
} ,
post ( newValue ) {
// my logic
}
}
}
} Вы можете просмотреть свои наблюдаемые государственные поля в объекте компонентов $watchers .
Расширить класс Exponent , чтобы создать компонент только с props это немного легче, чем Component . Быстрее подключаться и занимать меньше памяти.
import { Exponent } from 'domponent'
class StatelessThing extends Exponent{
constructor(conf){
super(conf);
}
}
Тогда у вас будет только доступ к:
propsWillUpdatepropsDidUpdate Зачем Exponent ??
Потому что он просто интерпретирует или излагает данные, которые даны ... и это звучит как компонент.
Компоненты или показатели будут предоставлены следующие поля.
| Имя поля | Тип | Доступ | Контекст | Описание |
|---|---|---|---|---|
| $ App | объект | публичный | Компонент/показатель | Все приложение Domponent |
| $ б | множество | частный | Компонент/показатель | Привязки EventListener для внутреннего использования |
| $ d | объект | частный | Компонент | Родительские компоненты ссылаются на своих детей |
| $ Key | нить | публичный | Компонент/показатель | Уникальный идентификатор для экземпляра компонента |
| $ name | нить | публичный | Компонент/показатель | Имя типа компонента |
| $ p | объект | частный | Компонент/показатель | Внутренняя коллекция реквизита и его ссылки на DOM |
| реквизит | объект | публичный | Компонент/показатель | Пары ключей/значения передаваемых данных |
| $ root | элемент | публичный | Компонент/показатель | Узел корня DOM компонента |
| $ s | объект | частный | Компонент | Внутренняя коллекция государства и его ссылки на DOM |
| состояние | объект | публичный | Компонент | Пары ключей/значения данных, которые могут быть обновлены |
| $ watchers | объект | публичный | Компонент | Хранившие функции изменений и их соответствующий состояние и ключ отпола |
Init ? Эта функция создает приложение и регистрирует все компоненты. Это принимает объект config в качестве необходимого аргумента:
const config = {
selector : document . getElementById ( "root" ) ,
components : { Counter } ,
appCreated : callbackFunction
} ;
const App = new Init ( config ) ;Затем он обнажает следующие методы:
И следующие объекты:
Вы также можете исключить объект components конфигурации и создать приложение без каких -либо компонентов для начала.
createComponent@Params:
App . createComponent ( document . getElementById ( "added-html" ) , callback ) ; register@Params
App . register ( NewComponent , callback ) ; deleteComponent@Params:
data-key или доступ к компоненту через this.$key App . deleteComponent ( "my-component-instance-key" , callback ) ; unregister@Params:
App . unregister ( "NewComponent" , callback ) ; Чтобы избежать атрибутов data- , столкновения с другими селекторами, библиотеками и т. Д. Вы можете переопределить имена атрибутов по умолчанию в объекте конфигурации приложения:
Init ( {
selector : getElementById ( 'root),
components : { Counter } ,
dataAttributes : {
component : 'mynamespace-component' ,
state : 'cool-state' ,
}
} ) ;Это означает, что ваш HTML будет выглядеть так:
< div data-mynamespace-component =" Counter " data-cool-state =' {"count":12} ' >
...
</ div >Вы можете при желании настроить синтаксис, который вы используете в HTML. Следующие элементы могут быть настроены.
INHERITS_FROM: '<-',
FROM_COMPONENT: '.',
KEY_VALUE: ':',
MULTIPLE_VALUES: "|",
METHOD_CALL: "->",
LIST: ","
Это означает, что в вашей конфигу вы можете добавить:
{
customSyntax : {
LIST : "!" ,
METHOD_CALL : "#"
}
}И ваш HTML может использовать это!
При разработке с Domponent используется сборка разработки добавляет полезные ошибки и журналы в вашу консоль из Development Dom (этот парень->)?
Самый простой способ использовать это - с помощью псевдонимов WebPack:
resolve : argv . mode === 'development' ? {
alias : {
domponent : 'domponent/dist/domponent.development.js'
}
} : { } ,Таким образом, ваша разработка сборка WebPack отменит производственную версию Domponent для версии, посвященной помощи от DOM.
Вы можете написать свой компонент HTML для различных шаблонных двигателей и включить их как частичные/фрагменты/что бы ваш двигатель называл «кусочками HTML».
Вот несколько примеров того, как вы можете использовать Domponent.
Примечание. Несмотря на эти синтаксические различия в наценке, помните, что компонент - это просто класс JS ✌
Пример синтаксиса мопса ?
// counter.pug
mixin counter ( count )
div ( data - component = "Counter" data - state = `
{
"count": count,
"isEven": count % 2 === 0
}
` )
p ( data - bind = "state:Counter.count" ) # { count }
button ( data - action = "click->Counter.increment" ) + 1
button ( data - action = "click->Counter.decrement" ) - 1
// usage
+ counter ( 101119 )
+ counter ( 61316 )Пример синтаксиса тимелиста ?
// counter.html
< div
data-component =" Counter "
th:fragment =" Counter "
th:data-state =' |{"count":${count}, "isEven": ${count % 2 == 0}}| '
>
< p data-bind =" state:Counter.count " th:text =" ${count} " > </ p >
< button data-action =" click->Counter.increment " >
+1
</ button >
< button data-action =" click->Counter.decrement " >
-1
</ button >
</ div >
// usage
< th:block th:replace =" ./counter.html :: Counter(count: 1289) " />
< th:block th:replace =" ./counter.html :: Counter(count: 491) " />Пример синтаксиса бритвы ⚔ Скоро ...
Пример синтаксиса Ruby on Rails ? вскоре...
Пример синтаксиса усов ? вскоре...
domponent [at] gmail [dot] com ( пожалуйста, используйте Domponent Support или мы не будем отвечать )@domponent