import { VNodeData } from 'vue/types/index' ; import { RootComponent , createRootFn , ChildrenRender } from './interface' ; import { throwError } from './utils' ; import { INSERT_POSITION_MAP } from './const' ; const createRoot = ( Vue , componentObject , data , childrenRender , options = { } ) => { const { target = 'body' , insertPosition = 'append' } = options ; let vNodeData ; let _childrenRender = childrenRender ; const container = 'string' === typeof target ? document . querySelector ( target ) : target ; if ( ! container ) { throwError ( 'target元素不存在' ) ; } const el = document . createElement ( 'div' ) ; container ! . insertAdjacentElement ( INSERT_POSITION_MAP [ insertPosition ] , el ) ; const root = new Vue ( { el , render ( createElement ) { return createElement ( componentObject , vNodeData , _childrenRender && _childrenRender ( createElement ) ) ; } , } ) ; const rootComponent = root . $children [ 0 ] as RootComponent ; rootComponent . $on ( 'hook:destroyed' , ( ) => { root . $destroy ( ) ; container ! . removeChild ( rootComponent . $el ) ; } ) ; rootComponent . $updateRenderData = ( newData , newChildrenRender ) => { if ( undefined !== newData ) { vNodeData = ( 'props' in newData ) ? newData : { props : newData } ; } _childrenRender = newChildrenRender ; root . $forceUpdate ( ) ; } ; rootComponent . $updateRenderData ( data , _childrenRender ) ; return rootComponent ; } ; export default createRoot ;