import React from 'react' ; import ReactDOM , { Renderer } from 'react-dom' ; import Vue , { CreateElement , PropType } from 'vue' ; type ReactRenderableElement = Parameters < Renderer > [ 0 ] | Parameters < typeof React . createElement > [ 0 ] ; param component returns function isReactComponentDefinition ( component ) { return typeof component === 'function' ; } /**
 * Vue component that renders a React Node, which is provided via props.
 * This component is part of the mechanism that allows using Slots/Children of the
 *  ReactWrapper inside a Vue component.
  export const VueChildrenWrapper = Vue . extend ( { props : { slotContent : { required : true , type : [ Object , Array , String , Function ] as PropType < ReactRenderableElement > } , reactProps : { } } , render ( h ) { return h ( 'div' , { staticClass : 'react-wrapper-slot' } ) ; } , mounted ( ) { this . $watch ( 'slotContent' , this . renderReactComponent , { immediate : true } ) ; this . $watch ( 'reactProps' , this . renderReactComponent ) ; } , methods : { renderReactComponent ( ) { if ( isReactComponentDefinition ( this . slotContent ) ) { const ReactComponent = this . slotContent as any ; ReactDOM . render ( < ReactComponent { ... this . reactProps } / > , this . $el ) ; } else { ReactDOM . render ( this . slotContent , this . $el ) ; } } } , beforeDestroy ( ) { const container = this . $root . $el . parentElement ; if ( container ) { const observer = new MutationObserver ( ( ) => { if ( ! this . $el . isConnected ) { observer . disconnect ( ) ; ReactDOM . unmountComponentAtNode ( this . $el ) ; } } ) ; observer . observe ( container , { subtree : true , childList : true , attributes : false } ) ; } else { ReactDOM . unmountComponentAtNode ( this . $el ) ; } } } ) ;