Цель этой обертки состоит в том, чтобы обеспечить постоянный интерфейс во всех виртуальных решениях DOM, которые обеспечивают виртуальную функцию DOM в стиле гиперрипта, а также предоставляют интерфейс по умолчанию для создания реального DOM. Это включает, но не ограничивается:
npm install @skatejs/valПроблемы, с которыми сталкиваются эти разные имплеменции, заключаются в том, что единственная распространенная вещь - это функция, которую вы вызываете, и аргументы, которые она принимает, на верхнем уровне. Однако все они ведут себя по -разному с аргументами, которые вы им даете.
Например, React будет устанавливать только реквизиты на элементы DOM, которые находятся в его белом списке. Preact установит реквизиты на элементы DOM, если они находятся in element . Есть проблемы с каждым из них.
Проблема с React в том, что вы не можете передавать сложные структуры данных в элементы DOM, которые обладают свойствами, которые не находятся в их белом списке, которым будет подвергаться каждый веб -компонент.
С Preact это в основном хорошо. Тем не менее, предположение состоит в том, что ваше пользовательское определение элемента определяется до того, как предварительно создает элемент DOM в его виртуальной реализации DOM. Это потерпит неудачу, если ваши пользовательские определения элементов загружены асинхронно, что не редкость, когда желание отложить загрузку некритических ресурсов.
Есть другие проблемы, такие как React, не работая вообще с пользовательскими событиями.
Лучшее решение, с которым я сталкивался до сих пор, - это создать обертку, которая работает для любого из них. Обертка позволяет несколько вещей:
attrs: {} во втором аргументе.)events: {} во втором аргументе).props: {} ) во втором аргументе).ref You будет завершен, чтобы val мог сделать свое дело. Это предполагает, что любая библиотека, которую вы оберкиваете, поддерживает обратный вызов ref как общий способ получить доступ к необработанному элементу DOM, который нам нужно использовать под капюшоном.
Использование простое. Вы импортируете обертку и вызываете ее единственным аргументом, являющейся виртуальной функцией DOM, которую вы хотите, чтобы она завершилась.
Реагировать:
import { createElement } from "react" ;
import val from "@skatejs/val" ;
export default val ( createElement ) ;Preact:
import { h } from "preact" ;
import val from "@skatejs/val" ;
export default val ( h ) ;В ваших компонентах вы затем импортируете свою обернутую функцию вместо одной из библиотеки.
/** @jsx h */
import h from "your-wrapper" ;
import { PureComponent } from "react" ;
import { render } from "react-dom" ;
class WebComponent extends HTMLElement { }
class ReactComponent extends PureComponent {
render ( ) {
return < WebComponent /> ;
}
}
render ( < ReactComponent /> , document . getElementById ( "root" ) ) ; Валь отправляется с адаптером по умолчанию, который генерирует реальные узлы DOM. Для этого просто импортируйте функцию h :
/** @jsx h*/
import { h } from "@skatejs/val" ;
// <div>test</div>
console . log ( < div > test </ div > . outerHTML ) ;Все работает так же, как рекламируется, так что вы все еще можете передавать пользовательские элементы, атрибуты и события, как обычно, и вещи просто работают.
Возможность сделать это очень полезно для тестирования реальных DOM и веб -компонентов. Применить либерально!
Атрибуты указываются с использованием объекта attrs .
import h from "your-wrapper" ;
h ( "my-element" , {
attrs : {
"my-attribute" : "some value"
}
} ) ; События связаны с использованием объекта events . Это работает для любых событий, включая пользовательские события.
import h from "your-wrapper" ;
h ( "my-element" , {
events : {
click ( ) { } ,
customevent ( ) { }
}
} ) ; Свойства классифицируются как все, что не является attrs или events .
h ( "my-element" , {
props : {
someProp : true
}
} ) ;Все остальное только проходит в вашу структуру.
// @jsx h
import val from "@skatejs/val" ;
import { createElement } from "react" ;
const h = val ( createElement ) ;
// The onClick prop gets passed through to React.
< button onClick = { ( ) => { } } /> ; Вы также можете использовать конструктор веб -компонентов вместо имени, который был передан customElements.define() .
// So we have the reference to pass to h().
class CustomElement extends HTMLElement { }
// It must be defined first.
customElements . define ( "custom-element" , CustomElement ) ;
// Now we can use it.
h ( CustomElement ) ;