L'objectif de ce wrapper est de fournir une interface cohérente sur toutes les solutions DOM virtuelles qui fournissent une fonction DOM virtuelle de style hyperscript, et fournissent également une interface par défaut pour créer un vrai DOM. Cela comprend, mais sans s'y limiter:
npm install @skatejs/valLes problèmes auxquels ces différents impléments sont confrontés est que la seule chose courante est la fonction que vous invoquez et les arguments qu'il accepte, au niveau supérieur. Cependant, ils se comportent tous différemment avec les arguments que vous leur donnez.
Par exemple, React ne définira que des accessoires sur les éléments DOM qui sont dans sa liste blanche. Preact définira des accessoires sur les éléments DOM s'ils sont in element . Il y a des problèmes avec chacun d'eux.
Le problème avec React est que vous ne pouvez pas transmettre des structures de données complexes aux éléments DOM qui ont des propriétés qui ne sont pas dans leur liste blanche, ce à quoi chaque composant Web serait soumis.
Avec Preact, c'est surtout bon. Cependant, l'hypothèse est que votre définition d'élément personnalisée est définie avant la création de préact de l'élément DOM dans son implémentation DOM virtuelle. Cela échouera si vos définitions d'éléments personnalisées sont chargées de manière asynchrone, ce qui n'est pas rare lorsque vous souhaitez reporter le chargement de ressources non critiques.
Il y a d'autres problèmes tels que React ne fonctionnent pas du tout avec des événements personnalisés.
La meilleure solution que j'ai rencontrée jusqu'à présent est de créer un wrapper qui fonctionne pour l'un d'eux. L'emballage permet plusieurs choses:
attrs: {} dans le deuxième argument.)events: {} dans le deuxième argument).props: {} ) dans le deuxième argument).ref que vous passez sera enveloppé pour que val puisse faire son truc. Cela suppose que la bibliothèque que vous enveloppez a une prise en charge d'un rappel ref comme moyen courant pour nous d'accéder à l'élément DOM RAW que nous devons utiliser sous le capot.
L'utilisation est simple. Vous importez l'emballage et l'invoquez avec le seul argument étant la fonction DOM virtuelle que vous souhaitez qu'il enveloppe.
Réagir:
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 ) ;Dans vos composants, vous importeriez ensuite votre fonction enveloppée au lieu de celle de la bibliothèque.
/** @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" ) ) ; Val est expédié avec un adaptateur par défaut qui génère des nœuds DOM réels. Pour ce faire, importez simplement la fonction h :
/** @jsx h*/
import { h } from "@skatejs/val" ;
// <div>test</div>
console . log ( < div > test </ div > . outerHTML ) ;Tout fonctionne comme annoncé, vous pouvez donc toujours transmettre des éléments, des attributs et des événements personnalisés comme vous le feriez normalement et les choses fonctionnent.
Être capable de le faire est extrêmement utile pour tester les composants DOM et Web réels. Postulez généreusement!
Les attributs sont spécifiés à l'aide de l'objet attrs .
import h from "your-wrapper" ;
h ( "my-element" , {
attrs : {
"my-attribute" : "some value"
}
} ) ; Les événements sont liés à l'aide de l'objet events . Cela fonctionne pour tous les événements, y compris les événements personnalisés.
import h from "your-wrapper" ;
h ( "my-element" , {
events : {
click ( ) { } ,
customevent ( ) { }
}
} ) ; Les propriétés sont classées comme tout ce qui n'est pas attrs ou events .
h ( "my-element" , {
props : {
someProp : true
}
} ) ;Tout le reste est passé à votre cadre.
// @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 = { ( ) => { } } /> ; Vous pouvez également utiliser votre constructeur de composants Web au lieu du nom qui a été transmis à 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 ) ;