
創建與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)