El objetivo de este envoltorio es proporcionar una interfaz consistente en todas las soluciones DOM virtuales que proporcionan una función DOM virtual de estilo HyperScript, y también proporcionan una interfaz predeterminada para crear DOM real. Esto incluye, pero no se limita a:
npm install @skatejs/valLos problemas que enfrentan estas implementaciones diferentes es que lo único común es la función que invoca y los argumentos que acepta, en un nivel superior. Sin embargo, todos se comportan de manera diferente con los argumentos que les da.
Por ejemplo, React solo establecerá accesorios en elementos DOM que están en su lista blanca. Preact establecerá accesorios en elementos DOM si están in element . Hay problemas con cada uno de estos.
El problema con React es que no puede pasar estructuras de datos complejas a elementos DOM que tienen propiedades que no están en su lista blanca, a las que cada componente web estaría sujeto.
Con Preact, es sobre todo bueno. Sin embargo, la suposición es que la definición de su elemento personalizado se define antes de preactuar la creación del elemento DOM en su implementación virtual de DOM. Esto fallará si sus definiciones de elementos personalizados se cargan de forma asincrónica, lo que no es infrecuente cuando desea diferir la carga de recursos no críticos.
Hay otros problemas, como React no trabajar en absoluto con eventos personalizados.
La mejor solución que he encontrado hasta ahora es crear un envoltorio que funcione para cualquiera de estos. El envoltorio habilita varias cosas:
attrs: {} en el segundo argumento).events: {} en el segundo argumento).props: {} ) en el segundo argumento).ref que pase se envolverá para que val pueda hacer lo suyo. Esto supone que cualquier biblioteca que esté envolviendo tiene soporte para una devolución de llamada ref como una forma común para que tengamos acceso al elemento DOM RAW que necesitamos usar debajo del capó.
El uso es simple. Importa el envoltorio e invoca con el único argumento que es la función DOM virtual que desea que envuelva.
Reaccionar:
import { createElement } from "react" ;
import val from "@skatejs/val" ;
export default val ( createElement ) ;Preactar:
import { h } from "preact" ;
import val from "@skatejs/val" ;
export default val ( h ) ;En sus componentes, importaría su función envuelta en lugar de la de la biblioteca.
/** @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 se envía con un adaptador predeterminado que genera nodos DOM reales. Para hacer esto, simplemente importe la función h :
/** @jsx h*/
import { h } from "@skatejs/val" ;
// <div>test</div>
console . log ( < div > test </ div > . outerHTML ) ;Todo funciona como se anuncia, por lo que aún puede pasar elementos personalizados, atributos y eventos como lo haría normalmente y las cosas simplemente funcionan.
Ser capaz de hacerlo es inmensamente útil para probar componentes de DOM y web reales. ¡Aplicar generosamente!
Los atributos se especifican utilizando el objeto attrs .
import h from "your-wrapper" ;
h ( "my-element" , {
attrs : {
"my-attribute" : "some value"
}
} ) ; Los eventos están vinculados utilizando el objeto events . Esto funciona para cualquier evento, incluidos eventos personalizados.
import h from "your-wrapper" ;
h ( "my-element" , {
events : {
click ( ) { } ,
customevent ( ) { }
}
} ) ; Las propiedades se clasifican como cualquier cosa que no sea attrs o events .
h ( "my-element" , {
props : {
someProp : true
}
} ) ;Cualquier otra cosa se pasa a su marco.
// @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 = { ( ) => { } } /> ; También puede usar su constructor de componentes web en lugar del nombre que se pasó a 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 ) ;