Das Ziel dieser Wrapper ist es, eine konsistente Schnittstelle über alle virtuellen DOM-Lösungen hinweg bereitzustellen, die eine virtuelle DOM-Funktion im HyperScript-Stil bieten und auch eine Standardschnittstelle zum Erstellen von realem DOM bereitstellen. Dies schließt, aber nicht beschränkt auf:
npm install @skatejs/valDie Probleme, die diese unterschiedlichen Implementierungen ausgesetzt sind, sind, dass die einzige gemeinsame Sache die Funktion ist, die Sie aufrufen, und die Argumente, die sie akzeptiert, auf einer oberen Ebene. Sie verhalten sich jedoch alle unterschiedlich mit den Argumenten, die Sie ihnen geben.
Beispielsweise setzt React nur Requisiten für DOM -Elemente, die in seiner Whitelist enthalten. Preact setzt Requisiten für DOM -Elemente, wenn sie in element sind. Es gibt Probleme mit jedem von diesen.
Das Problem mit React ist, dass Sie nicht komplexe Datenstrukturen an DOM -Elemente übergeben können, die Eigenschaften haben, die nicht in ihrer Whitelist sind und denen jede Webkomponente unterliegt.
Bei Preact ist es meistens gut. Es wird jedoch davon ausgegangen, dass Ihre benutzerdefinierte Elementdefinition vor dem Erstellen des DOM -Elements in seiner virtuellen DOM -Implementierung definiert wird. Dies schlägt fehl, wenn Ihre benutzerdefinierten Elementdefinitionen asynchron geladen werden. Dies ist nicht ungewöhnlich, wenn Sie die Belastung nichtkritischer Ressourcen verschieben möchten.
Es gibt andere Probleme wie React, die überhaupt nicht mit benutzerdefinierten Ereignissen arbeiten.
Die beste Lösung, auf die ich bisher gestoßen bin, ist, einen Wrapper zu erstellen, der für eine dieser Teile funktioniert. Der Wrapper ermöglicht mehrere Dinge:
attrs: {} im zweiten Argument.)events: {} im zweiten Argument).props: {} ) festgelegt werden).ref den Sie passieren, wird verpackt, damit val sein Ding tun kann. Dies setzt voraus, dass in jeder Bibliothek, die Sie wickeln, einen ref -Callback für uns unterstützt, um Zugriff auf das Roh -DOM -Element zu erhalten, das wir unter der Motorhaube verwenden müssen.
Die Verwendung ist einfach. Sie importieren den Wrapper und rufen ihn mit dem einzigen Argument auf die virtuelle DOM -Funktion auf, die Sie erstellen sollen.
Reagieren:
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 ) ;In Ihren Komponenten würden Sie Ihre verpackte Funktion anstelle der aus der Bibliothek importieren.
/** @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 wird mit einem Standardadapter ausgeliefert, der echte Dom -Knoten generiert. Importieren Sie dazu einfach die h -Funktion:
/** @jsx h*/
import { h } from "@skatejs/val" ;
// <div>test</div>
console . log ( < div > test </ div > . outerHTML ) ;Alles funktioniert wie angekündigt, sodass Sie weiterhin benutzerdefinierte Elemente, Attribute und Ereignisse verabschieden können, wie Sie es normalerweise tun und die Dinge einfach funktionieren.
Dies zu können, ist immens nützlich, um echte DOM- und Webkomponenten zu testen. Sich liberal bewerben!
Attribute werden unter Verwendung des attrs -Objekts angegeben.
import h from "your-wrapper" ;
h ( "my-element" , {
attrs : {
"my-attribute" : "some value"
}
} ) ; Ereignisse werden mit dem events gebunden. Dies funktioniert für alle Veranstaltungen, einschließlich benutzerdefinierter Ereignisse.
import h from "your-wrapper" ;
h ( "my-element" , {
events : {
click ( ) { } ,
customevent ( ) { }
}
} ) ; Eigenschaften werden als alles eingestuft, was nicht attrs oder events ist.
h ( "my-element" , {
props : {
someProp : true
}
} ) ;Alles andere wird nur in Ihren Rahmen übergeben.
// @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 = { ( ) => { } } /> ; Sie können auch Ihren Webkomponentenkonstruktor anstelle des Namens verwenden, der an 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 ) ;