在Bootstrap模态框中加载Vue 3页面时出现createApp重复声明的语法错误
嘿,这个问题我太熟了!你碰到的SyntaxError: Identifier 'createApp' has already been declared错误,本质是两个页面的脚本共享了同一个全局作用域导致的。
当你用Bootstrap模态框加载page2.html时,它会把page2的HTML内容插入到当前page1的DOM中,这意味着两个页面的<script>代码都会在同一个全局环境里执行。而你在两个脚本里都用const声明了createApp和ref——const声明的变量在同一作用域下是不允许重复定义的,这就触发了语法错误。
给你几个实用的解决方案,按推荐程度排序:
方案1:用立即执行函数表达式(IIFE)隔离作用域
这是最简单直接的修复方式,把每个页面的Vue代码包裹在IIFE里,让变量成为局部作用域的私有变量,避免全局冲突。
修改page1.html的脚本:
<script> (function() { const { createApp, ref } = Vue; createApp({ setup() { const user_id = ref(); return { user_id }; } }).mount('#app_page1'); })(); </script>
修改page2.html的脚本:
<script> (function() { const { createApp, ref } = Vue; createApp({ setup() { const files = ref(); return { files }; } }).mount('#app_page2'); })(); </script>
IIFE会创建一个独立的函数作用域,里面的createApp和ref只会在这个作用域内生效,不会和其他脚本的变量产生冲突。
方案2:使用ES模块(推荐长期项目)
如果你的项目适合模块化开发,可以把脚本改成ES模块模式,每个脚本都是独立的模块,变量默认是私有的,不会泄漏到全局作用域。
修改page1.html的脚本(需要使用Vue的ES模块版本):
<script type="module"> import { createApp, ref } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'; createApp({ setup() { const user_id = ref(); return { user_id }; } }).mount('#app_page1'); </script>
page2.html的脚本同理修改即可。这种方式更符合现代前端开发的规范,也能从根本上避免全局变量冲突的问题。
方案3:全局变量检查(不推荐,仅作应急)
如果你暂时不想改结构,可以用let替代const,并在声明前检查变量是否存在:
<script> let createApp, ref; if (!createApp) { ({ createApp, ref } = Vue); } createApp({ setup() { const user_id = ref(); return { user_id }; } }).mount('#app_page1'); </script>
不过这种方式会污染全局作用域,可能带来其他潜在问题,所以只建议临时应急使用。
总的来说,方案1和方案2都是比较靠谱的解决方式,根据你的项目情况选一个就行啦!
备注:内容来源于stack exchange,提问作者aknd

