
创建与React生态系统的所有好处的真正可重复使用和可互操作的框架不可用的组件 - 使用HTML5自定义元素API扩展HTML的词汇。
npm install react-standalone --save 看看mars-weather组件,以了解如何构建可重复使用的组件(但是本质上是一个由标签名称组成的组件),例如mars-weather ,React component和使用osom可选架构。
import { createModule } from 'standalone' ;
import schema from './schema' ;
import component from './component' ;
export default createModule ( 'mars-weather' , { schema , component } ) ;创建软件包后,将使用提供的tagName创建一个自定义元素,该元素可以嵌入到DOM中 - 所有React LifeCycle方法都将被调用,例如当将元素从DOM中删除时,例如componentWillUnmount 。
< mars-weather />由于mars-weather组件是一个完全自定义的元素,因此它可以嵌入任何JavaScript框架中 - Angular,vue,vue,react,cycle,cycle,ember,ember,nilla等...
奖励:将KEO与阴影边界使用真正的聚合物风格。
通过在自定义元素上指定属性,将属性的值传递到您的组件中,作为道具 - 对state的任何更改都将在内部与您的组件进行处理,而对元素属性的任何更改都会通过更新的props引起重新渲染。
在mars-weather示例中,我们设置了getDefaultProps方法以返回默认道具,但是用户可以通过传递名为data-unit的data属性来覆盖unit道具。
< mars-weather data-unit =" C " />在上述情况下, data-unit属性将转换为unit - Standalone剥离任何data-前缀,然后重新呈现您的组件,从而使您可以访问this.props.unit的属性。
由于所有HTML属性都是string S, Standalone允许您为组件指定架构,这将将string属性转换为您使用osom期望的数据类型。
export default {
unit : {
type : String ,
default : 'F'
}
} ;一旦配置了用于组件的模式,就可以愉快地设置通常的反应propTypes ,以指定您期望通过的数据类型。
使用自定义事件,您可以在组件和外界之间轻松设置通信渠道。
// Instantiate `CustomEvent` and then specify the name of the event, followed
// by the payload which will be passed to your listener function.
const event = new CustomEvent ( 'migrate-planets' , {
bubbles : true ,
detail : {
planet : 'Saturn'
}
} ) ;
findDOMNode ( this ) . dispatchEvent ( event ) ;至关重要的是,您将事件散发为bubbles: true否则,事件只会停止在findDOMNode(this)节点上停止,而不是在mars-weather节点上冒泡 - 除非您使用findDOMNode(this).parentNode在mars-weather节点上派遣事件。
在您的组件中,您会使用dispatchEvent发出事件 - CustomEvent ,然后使用addEventListener从外部绑定自定义元素(例如mars-weather )。
const node = document . querySelector ( 'mars-weather' ) ;
node . addEventListener ( 'migrate-planets' , event => {
// Update the `data-planet` attribute to reflect the newly migrated planet
// which will cause the component to re-render with the update prop.
node . setAttribute ( 'data-planet' , event . detail . planet ) ;
} ) ;由于在组件上调用setAttribute是为了重新渲染组件的反应,因此向组件提供JSON有效载荷可能很有用,尤其是在定义多种属性的情况下;这也有助于提高性能,因为您只需要一个setAttribute就可以更新许多道具和重新渲染。
通过定义模式,您可以指定将被解析为JSON的属性。
export default {
payload : {
type : JSON . parse
}
}将JSON字符串连接到元素的data-payload属性将导致使用JSON.parse将其解析PropTypes.shape propTypes中,并将this.props.payload传递给您的React组件。
所有Standalone组件都扩展了HTMLElement.prototype ,并允许将自定义功能添加到该元素中 - 一旦有了对关联元素的引用,您就可以调用该功能。看看mars-weather的方法以示例。
const getWeather = function ( ) {
const weather = this . component . state . weather . atmoOpacity . toLowerCase ( ) ;
return `The current weather on Mars is ${ weather } !` ;
} ;
// ...
document . querySelector ( 'mars-weather' ) . getWeather ( ) ;当将组件附加到DOM上时,它将更新其HTMLElement原型,以将渲染的组件分配给getPrototypeOf(this).component这很方便地允许您访问props and state ,并调用React组件内部的功能。
值得注意的是,只有将this.component添加到DOM后才可用。
使用自定义元素API,可以扩展现有元素 - 使用is属性进行专业化。 Standalone允许您通过传递元素进行扩展来扩展元素。
// Creates a `mars-weather` element.
export default createModule ( 'mars-weather' , { schema , methods , component } ) ;
// Creates a `input[is="mars-weather"]` element.
export default createModule ( 'input/mars-weather' , { schema , methods , component } ) ;值得注意的是,当您扩展已知元素时,您的元素将扩展其原型 - 在mars-weather元素上方的情况下,将扩展input及其HTMLInputElement原型。
*需要出色的WebComponents-lite.js Polyfill(13k Gzpipped)