
Создайте фреймворки агностические компоненты, которые действительно используются многократно используемыми и совместимыми со всеми преимуществами экосистемы React - используя API пользовательских элементов HTML5 для расширения словаря HTML.
npm install react-standalone --save Взгляните на компонент mars-weather для идеи о том, как структурировать свой многоразовый компонент-однако, по сути, компонент состоит из имени тега, таких как mars-weather , component React и дополнительная схема с использованием osom .
import { createModule } from 'standalone' ;
import schema from './schema' ;
import component from './component' ;
export default createModule ( 'mars-weather' , { schema , component } ) ; После того, как вы создали свой пакет, будет создан пользовательский элемент с предоставленным tagName , который может быть встроен в DOM - все методы жизненного цикла React будут вызваны, например, componentWillUnmount , когда элемент был удален из DOM.
< mars-weather /> Поскольку компонент mars-weather является совершенно индивидуальным элементом, он может быть встроен в любую каркас JavaScript-Angular, Vue, React, Cycle, Ember, Vanilla и т. Д.
Бонус: используйте Keo с тенью границы для истинного ощущения в стиле полимера.
Определяя атрибуты на пользовательском элементе, значения атрибутов передаются в ваш компонент в качестве реквизита-любые изменения в state будут рассматриваться внутренне к вашему компоненту, тогда как любые изменения в атрибутах вашего элемента будут вызывать повторный дрендер с обновленными props .
В примере mars-weather мы настроили метод getDefaultProps для возврата репутации по умолчанию, однако пользователи могут переопределить unit опору, передавая атрибут data с именем 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 React, указав тип данных, который вы ожидаете пройти.
Используя пользовательские события, вы можете легко настроить канал связи между вашими компонентами и внешним миром.
// 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 -если вы не отправляете событие на узле mars-weather , используя findDOMNode(this).parentNode .
В рамках вашего компонента вы излучаете событие- CustomEvent -используя dispatchEvent , а затем связываете свой пользовательский элемент-такой как mars-weather -с помощью addEventListener извне.
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 , и передается в ваш компонент React propTypes как this.props.payload PropTypes.shape
Все 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 и 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 .
* Требуется отличный полифилл Webmponents-lite.js (13K GZIPPED)