vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
45.61k stars 8k forks source link

使用h函数和render函数挂载组件,组件引用的全局UI组件无法正常解析渲染 #11208

Closed TurbMZ closed 1 week ago

TurbMZ commented 1 week ago

Vue version

3.3.9

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-twm44h?file=src%2Fcomponents%2Fcommand.js

Steps to reproduce

import { h, render } from 'vue'

// 弹层组件 const componentMap = { CustomDialog: defineAsyncComponent( () => import('@/components/CustomDialog.vue') ) }

export default function useCommandDialog() { function showDialog(config: IDialogCommandConfig) { const component = componentMap[config.component] const mountedEl = (config.container || document.body.querySelector('#app')) as HTMLElement const componentVnode = h(component, { ...config.props }) console.log('commandDialog', componentVnode, component)

// // 挂载弹窗组件
render(componentVnode, mountedEl)
setTimeout(() => {
  if (componentVnode.component && componentVnode.component.proxy) {
    const AsyncComInstance = componentVnode.component
    const realComponent = AsyncComInstance.subTree.component
    // console.log('render', AsyncComInstance.subTree)
    if (realComponent && realComponent.isMounted && realComponent.exposed) {
      realComponent.exposed[config.openFnName] && realComponent.exposed[config.openFnName]()
    }
  }
}, 80)

}

return { showDialog } }

What is expected?

希望正常显示弹窗组件和组件引用的UI组件

What is actually happening?

报错: Failed to resolve component: a-select If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement

System Info

No response

Any additional comments?

No response

linzhe141 commented 1 week ago

应该使用Telport 如果使用render,是不会关联main.js里面的rootApp的,

image image

所以在resolveComponent就根本找不到rootApp注册的全局组件

image

TurbMZ commented 1 week ago

应该使用Telport 如果使用render,是不会关联main.js里面的rootApp的, image image 所以在resolveComponent就根本找不到rootApp注册的全局组件 image

实际项目里面modal是使用了Telport包裹的 model

这里这个useCommandDialog是想要把业务弹窗组件改成函数式调用,减少业务组件在代码中的引用代码。例如这种 业务引用代码

linzhe141 commented 1 week ago

应该使用Telport 如果使用render,是不会关联main.js里面的rootApp的, image image 所以在resolveComponent就根本找不到rootApp注册的全局组件 image

实际项目里面modal是使用了Telport包裹的 model

这里这个useCommandDialog是想要把业务弹窗组件改成函数式调用,减少业务组件在代码中的引用代码。例如这种 业务引用代码

你是用render进行挂载的吗,如果是render到某一个节点下,是不会获取到全局组件的

TurbMZ commented 1 week ago

应该使用Telport 如果使用render,是不会关联main.js里面的rootApp的, image image 所以在resolveComponent就根本找不到rootApp注册的全局组件 image

实际项目里面modal是使用了Telport包裹的 model 这里这个useCommandDialog是想要把业务弹窗组件改成函数式调用,减少业务组件在代码中的引用代码。例如这种 业务引用代码

你是用render进行挂载的吗,如果是render到某一个节点下,是不会获取到全局组件的

是的。。没其他办法了吗