以下是对两个 Vue 3 示例代码的详细对比分析,它们在实现相同功能时采用了不同的技术方案:
示例 1:传统全局引入方式
html复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<!-- 全局引入 Vue 3 -->
<script src="https://cdn.staticfile.net/vue/3.0.5/vue.global.js"></script>
</head>
<body>
<div id="hello-vue" class="demo">
{{ message }}
</div>
<script>
// 定义应用配置对象
const HelloVueApp = {
data() {
return {
message: 'Hello Vue!!'
}
}
}
// 使用全局 Vue 对象创建应用
Vue.createApp(HelloVueApp).mount('#hello-vue')
</script>
</body>
</html>
示例 2:ES 模块化方式
html复制代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
</head>
<body>
<div id="app">{{ message }}</div>
<!-- 使用 ES 模块 -->
<script type="module">
// 从 CDN 导入特定 API
import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'
// 直接创建应用
createApp({
data() {
return {
message: 'Hello RUNOOB!'
}
}
}).mount('#app')
</script>
</body>
</html>
核心差异对比表
特性 | 示例 1 (传统全局引入) | 示例 2 (ES 模块化) | 优势分析 |
---|---|---|---|
Vue 引入方式 | <script src="vue.global.js"> |
import { createApp } from '...' |
示例 2 更现代,避免全局命名污染 |
脚本类型 | 普通脚本 (<script> ) |
ES 模块 (<script type="module"> ) |
示例 2 支持模块化开发 |
API 使用 | Vue.createApp() (全局对象) |
createApp() (按需导入) |
示例 2 更符合现代框架使用习惯 |
构建版本 | vue.global.js (完整运行时) |
vue.esm-browser.js (ESM 优化版) |
示例 2 支持 Tree-shaking 潜力 |
数据定义 | 命名配置对象 (HelloVueApp ) |
匿名配置对象 (直接内联) | 示例 2 更简洁 |
挂载点 | #hello-vue (带 class) |
#app (更简洁) |
无本质差异 |
浏览器兼容性 | IE11+ (兼容性好) | 现代浏览器 (Chrome/Firefox/Edge/Safari) | 示例 1 兼容性更好 |
应用场景 | 快速原型/简单页面/兼容旧浏览器 | 现代项目/学习 ES 模块/无构建工具开发 | 根据需求选择 |
包体积 | ~40KB (完整运行时) | ~40KB (但支持按需加载) | 示例 2 有优化空间 |
关键差异详解
模块系统演进
- 示例 1:使用传统的全局变量模式(IIFE 打包)
- 将整个 Vue 库绑定到
window.Vue
- 所有功能全局可用
- 将整个 Vue 库绑定到
- 示例 2:使用原生 ES 模块
- 只导入需要的
createApp
函数 - 避免全局命名空间污染
- 只导入需要的
- 示例 1:使用传统的全局变量模式(IIFE 打包)
应用创建方式
javascript复制代码
// 示例1:通过全局对象 Vue.createApp(...) // 示例2:直接使用导入的函数 createApp(...)
开发体验差异
- 示例 2 支持顶级
await
等现代 JS 特性 - 示例 2 天然支持模块依赖管理
- 示例 2 在控制台错误提示更清晰(含模块信息)
- 示例 2 支持顶级
性能特点
指标 示例 1 示例 2 首次加载 立即执行 需解析模块依赖 缓存效率 全局缓存 模块级缓存 按需加载潜力 ❌ 全量加载 ✅ 理论可行 (需 CDN 支持) 生产环境建议
- 示例 1 方式:适合嵌入第三方平台的简单组件
- 示例 2 方式:适合 PWA/现代 Web 应用
- 共同限制:对于复杂应用,两者都不如 Vite 构建方案
- 缺少 HMR 热更新
- 无代码分割优化
- 无预处理器支持
为什么示例 2 更代表未来趋势?
- 符合 ESM 标准:浏览器原生模块支持已成为标准
- 更好的代码组织:
javascript复制代码
// 可轻松扩展为 import { createApp, ref } from 'vue' import router from './router.js'
- 与现代工具链兼容:可平滑迁移到 Vite 等构建工具
- 渐进式加载:为未来实现模块按需加载奠定基础
迁移建议:新项目优先使用示例 2 的方式,旧项目可逐步迁移。但最终复杂项目都应转向基于 Vite 的完整工程化方案。