You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在单HTML页面中创建并使用多个独立Vue2应用(结合Django)

多Vue应用独立挂载到Django页面并隔离的解决方案

问题背景

刚接触Vue,正在已完成一半的Django应用中集成Vue + Vuetify + Vuex前端,需要将多个Vue应用独立挂载到HTML页面的不同div中。当前代码可运行,但存在一个应用的模态窗口会在另一个先挂载的应用中打开的问题,且无法采用单入口结合Vue Router的方案,必须由Django提供嵌入Vue组件的HTML页面。

当前配置代码

HTML页面(Django模板)

<div class="tab-content" id="settings-tab-content">
    <script type="application/json" id="initial-data">
        { "is_superuser": {{ is_superuser|lower }} }
    </script>

    <div class="tab-pane fade" id="groups-tab-content" role="tabpanel" aria-labelledby="groups-tab">
        <div id="userGroups"></div>
    </div>

    <div class="tab-pane fade" id="structure-tab-content" role="tabpanel" aria-labelledby="structure-tab">
        <div id="app"></div>
    </div>
</div>

Vue入口JS

import Vue from 'vue'
import clinicStructure from './clinicStructure.vue'
import userGroups from './userGroups.vue'
import router from './router'
import store from './store'
import vuetify from './plugins/vuetify'
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/dist/vuetify.min.css'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  vuetify,
  render: h => h(clinicStructure)
}).$mount('#app')

new Vue({
  router,
  store,
  vuetify,
  render: h => h(userGroups)
}).$mount('#userGroups')

package.json构建脚本

{
  "build": "vue-cli-service build --dest=../../static/builds/prod",
  "dev": "vue-cli-service build --dest=../../static/builds/dev --mode=development --watch"
}

问题原因

当前代码中,两个Vue实例共用了同一个Vuetify、Router和Store实例,导致Vuetify的全局组件(如模态框)的上下文被绑定到第一个挂载的实例上,进而出现模态窗口串到其他应用的问题。

解决方案

核心思路是让每个Vue应用拥有独立的核心实例(Vuetify、Router、Store),彻底隔离应用间的上下文:

1. 修改Vue入口JS,为每个应用创建独立实例

import Vue from 'vue'
import clinicStructure from './clinicStructure.vue'
import userGroups from './userGroups.vue'
// 导入Router和Store的创建函数而非现成实例
import { createRouter } from './router'
import { createStore } from './store'
import Vuetify from 'vuetify'
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/dist/vuetify.min.css'

Vue.config.productionTip = false
Vue.use(Vuetify)

// 第一个应用:clinicStructure
new Vue({
  router: createRouter(), // 独立Router实例
  store: createStore(),   // 独立Store实例(如需共享状态可改为导入同一个store)
  vuetify: new Vuetify(), // 独立Vuetify实例
  render: h => h(clinicStructure)
}).$mount('#app')

// 第二个应用:userGroups
new Vue({
  router: createRouter(), // 独立Router实例
  store: createStore(),   // 独立Store实例
  vuetify: new Vuetify(), // 独立Vuetify实例
  render: h => h(userGroups)
}).$mount('#userGroups')

2. 调整Router和Store的导出方式

确保router/index.js和store/index.js导出的是创建实例的函数,而非直接导出实例:

router/index.js示例

import Vue from 'vue'
import VueRouter from 'vue-router'
import SomeComponent from '../views/SomeComponent.vue'

Vue.use(VueRouter)

export function createRouter() {
  const routes = [
    // 该应用的路由配置
    { path: '/some-path', component: SomeComponent }
  ]

  return new VueRouter({
    routes
  })
}

store/index.js示例

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export function createStore() {
  return new Vuex.Store({
    state: {
      // 该应用的状态
    },
    mutations: {
      // 该应用的mutations
    },
    actions: {
      // 该应用的actions
    }
  })
}

3. 额外注意事项

  • 如果需要在多个应用间共享部分状态,可以将这部分状态抽离到独立模块,在createStore中引入,但每个应用仍需创建独立的Store实例。
  • 确保每个Vue应用的根组件没有使用全局事件总线(如Vue.prototype.$bus),避免应用间的事件干扰。
  • Vuetify的全局配置(如主题)可以在new Vuetify()时统一传入,保证样式一致性的同时保持实例独立。

内容的提问来源于stack exchange,提问作者Iliya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:49:51