为何将同一个Vue实例挂载到两个div仅第一个生效?
问题排查:同一Vue实例挂载多个DOM元素失效
问题原因
Vue中通过createApp()创建的应用实例仅支持挂载到单个DOM元素。当你第二次调用app1.mount('#div2app1')时,Vue会先卸载之前挂载在#div1app1上的实例,再将该实例重新挂载到#div2app1上。这就导致第一个div失去响应式绑定,第二个div虽然完成挂载,但实例的生命周期钩子(比如onMounted)只会在最终挂载时执行一次,最终表现为只有第一个div能正常渲染数据。
解决方案
方案一:创建多个独立的应用实例
如果不需要共享状态,可将app1的逻辑封装为工厂函数,每次调用生成新的实例,分别挂载到不同DOM元素:
<script type="module"> import { createApp, ref, onMounted } from 'vue' // 封装app1的逻辑为工厂函数 const createApp1 = () => createApp({ setup() { onMounted(async () => { console.log('Hello') message.value = 'New Hello' }) const message = ref('Hello Vue!') return { message } } }) const app2 = createApp({ setup() { onMounted(async () => { console.log('Hello') msg.value = 'Hello for App2' }) const msg = ref('Hello Vue!') return { msg } } }) // 创建两个独立的app1实例,分别挂载 createApp1().mount('#div1app1'); createApp1().mount('#div2app1'); app2.mount('#div1app2'); </script>
方案二:封装为可复用组件(支持状态共享)
如果希望两个div共享同一状态,可将app1的逻辑封装成组件,注册后在多个位置复用:
<div id="root"> <div id="div1app1"> <app1-component></app1-component> </div> <!--lots of html an JS in between --> <div id="div1app2"> <app2-component></app2-component> </div> <!--lots of html an JS in between --> <div id="div2app1"> <app1-component></app1-component> </div> </div> <script type="module"> import { createApp, ref, onMounted } from 'vue' // 封装app1组件 const App1Component = { setup() { onMounted(async () => { console.log('Hello') message.value = 'New Hello' }) const message = ref('Hello Vue!') return { message } }, template: `This is div for app1 {{ message }}` } // 封装app2组件 const App2Component = { setup() { onMounted(async () => { console.log('Hello') msg.value = 'Hello for App2' }) const msg = ref('Hello Vue!') return { msg } }, template: `This is div for app2 {{ msg }}` } // 创建根实例并注册组件 const app = createApp({}) app.component('app1-component', App1Component) app.component('app2-component', App2Component) app.mount('#root'); </script>
内容的提问来源于stack exchange,提问作者joseph son
相关产品推荐
相关产品推荐

