如何在Vue3嵌套应用(Vue应用内嵌另一Vue应用)中获取$refs
问题根因
Vue3 独立应用实例的挂载节点本身不在当前应用的模板编译范围内,挂载节点上声明的ref属性会被外层包裹它的Vue应用解析、收集到自身的$refs中。内层应用初始化编译时,只会处理挂载节点内部的模板内容,不会解析挂载节点自身的属性,自然无法在自身的$refs里拿到挂载节点的引用,这和你观测到的现象完全一致。
可落地的实现方式
直接通过实例属性获取根节点
单根节点模式下,Vue3应用挂载完成后,this.$el就是当前应用对应的根DOM节点,不需要额外声明ref就能直接拿到:// 内层appInner的mounted钩子 mounted() { const rootEl = this.$el console.log('内层应用根节点', rootEl) // 如果是多根fragment模式,直接用选择器拿即可 // const rootEl = document.getElementById('appInner') }这种方式不需要调整现有模板结构,改造成本最低。
把ref声明迁移到应用模板内部
不要在挂载容器节点上写Vue相关的指令、属性,把带ref的根节点放到内层应用自身的模板里,就能被正常解析到$refs:
首先调整页面里的挂载容器,移除节点上的ref属性:<div id="appInner"></div>然后在内层应用的配置中声明根模板:
const innerConfig = { template: ` <div ref="appInner"> <!-- 原有业务内容全部迁移到这里 --> </div> `, mounted() { console.log('根节点ref', this.$refs.appInner) // 可正常获取 } // 其余原有配置保持不变 } const appInner = createApp(innerConfig) appInner.mount('#appInner')跨实例通信不建议依赖DOM引用
两个独立挂载的Vue应用不属于常规的父子组件关系,如果是为了实现应用间的数据、方法共享,优先用全局状态、或者外层实例挂载后做全局派发的方式实现,直接跨实例拿DOM会提高后续维护的耦合成本。
内容的提问来源于stack exchange,提问作者CodeBerry
相关产品推荐
相关产品推荐

