资讯动态

Vue3项目实战:从零到一,快速上手Vite与Vue CLI创建项目

发布时间:2026/8/29 15:28:25 来源:尧图企业网站定制
1. 项目概述为什么现在必须掌握Vue3如果你是一名前端开发者或者正准备踏入这个领域那么“Vue3”这个词现在几乎无处不在。从各大公司的招聘要求到社区里热火朝天的讨论再到你手头可能正在维护的老项目升级到Vue3似乎成了一道必选题。但面对一个已经成熟的Vue2生态很多朋友会困惑我真的需要学吗从我的实际项目经验和团队协作来看答案是肯定的。Vue3不仅仅是一次版本迭代它从底层设计到开发体验都带来了质的飞跃尤其是其基于Proxy的响应式系统和Composition API让构建和维护大型复杂应用变得前所未有的清晰和高效。这篇内容我将从一个一线开发者的视角带你绕过那些官方文档里冗长的概念直接进入实战。我们会聚焦于最核心的“快速上手”环节用两种最主流的方式Vue CLI和Vite从零创建一个Vue3项目并深入项目骨架的几个关键源码文件main.ts、App.vue等理解它们是如何协同工作的。我的目标很简单让你在30分钟内不仅能跑起来一个Vue3项目更能看懂它、掌控它为后续深入学习setup、ref、reactive等核心概念打下坚实基础。无论你是Vue2的老手想平滑过渡还是完全的新手这篇指南都将提供一条清晰、可复现的路径。2. 环境准备与两种创建方式的深度对比在动手写代码之前确保你的开发环境就绪是第一步。这里没有太多花哨的东西但基础的稳固决定了后续效率。2.1 基础环境配置Node.js与包管理器Vue3的构建工具依赖于Node.js环境。我强烈建议你使用Node.js 16.0.0或更高版本这是大多数现代前端工具链顺畅运行的基础。你可以去Node.js官网下载LTS长期支持版本安装过程一路下一步即可。安装完Node.js包管理器npm会随之安装。但为了提高依赖安装的速度和稳定性我推荐你同时安装yarn或pnpm。尤其是pnpm它采用硬链接方式能极大节省磁盘空间并提升安装速度。你可以通过npm来安装它们# 安装yarn npm install -g yarn # 安装pnpm npm install -g pnpm注意在Windows系统上全局安装有时会遇到权限问题。如果遇到EACCES错误可以考虑使用nvm-windowsNode Version Manager来管理多个Node.js版本或者以管理员身份运行命令行工具。在Mac/Linux上有时需要在命令前加sudo。完成这些后打开你的终端命令行分别输入node -v、npm -v以及你安装的包管理器命令如yarn -v或pnpm -v来验证安装是否成功。看到版本号输出就意味着你的“地基”已经打好了。2.2 创建方式一使用Vue CLI传统而稳健Vue CLIVue Command Line Interface是Vue.js官方长期维护的标准化项目脚手架。在Vue2时代它是绝对的主流。对于Vue3它依然提供完善的支持特别适合从Vue2项目迁移或者团队习惯于Webpack构建流程的场景。操作步骤与核心解析全局安装/升级Vue CLI 首先你需要确保安装的是Vue CLI 4.5及以上版本这个版本才开始稳定支持Vue3。npm install -g vue/cli # 或 yarn global add vue/cli安装后运行vue --version检查版本。创建项目 在你想放置项目的目录下执行创建命令。vue create my-vue3-app这里的my-vue3-app是你的项目名称可以按需修改。关键交互式选择 执行命令后你会进入一个交互式的配置界面这里是重点第一步选择预设Preset。如果你没有保存过自定义预设这里选择“Manually select features”手动选择特性。第二步选择项目特性。用上下箭头移动空格键选中/取消。对于Vue3项目务必确保选中“Vue Version”这一项然后才会在下一步让你选择Vue3。其他如Babel、TypeScript、Router、Vuex等根据你的项目需求选择。对于新手快速上手可以只选Babel和Vue Version。第三步选择Vue版本。当上一步选中“Vue Version”后这里会出现“3.x”的选项选择它。第四步后续配置。剩下的配置如路由模式history/hash、CSS预处理器Sass/Less、代码规范工具ESLint等按需选择或使用默认值即可。对于代码规范我建议新手可以先跳过选择“In dedicated config files”或默认避免初期被复杂的规则困扰。等待安装并运行 选择完成后Vue CLI会自动安装依赖。这个过程取决于网络速度。完成后按照提示进入项目目录并启动开发服务器cd my-vue3-app npm run serve # 或 yarn serve控制台会输出本地服务器地址通常是http://localhost:8080在浏览器中打开它你就能看到Vue的欢迎页面了。Vue CLI创建方式的特点与心得优点生态成熟配置全面与Webpack深度集成适合复杂的企业级项目配置如多入口、自定义Webpack Loader等。从Vue2迁移过来几乎无认知成本。缺点项目依赖较重安装和启动速度相对于Vite较慢。配置虽然灵活但Webpack的配置对于新手来说可能是个“黑盒”一旦需要深度定制学习曲线较陡。实操心得如果你或你的团队已经有成熟的Vue2项目配置比如特定的vue.config.js想平稳升级到Vue3那么继续使用Vue CLI是风险最低的选择。它的“稳健”体现在对历史包袱的兼容性上。2.3 创建方式二使用Vite现代而迅猛Vite是Vue作者尤雨溪开发的下一代前端构建工具。它利用了现代浏览器原生支持ES模块的特性在开发阶段实现了极速的热更新体验非常流畅。对于新建的Vue3项目Vite目前是官方更推荐的方式。操作步骤与核心解析创建项目 使用Vite创建项目不需要全局安装任何CLI工具直接使用npm、yarn或pnpm即可。# 使用 npm npm create vuelatest # 使用 yarn yarn create vue # 使用 pnpm pnpm create vue运行上述命令后它会自动下载并执行create-vue这个官方脚手架工具。关键交互式选择 与Vue CLI类似也会进入交互式配置但选项更聚焦于Vue3的现代生态项目名称输入你的项目名如my-vite-vue3-app。是否添加TypeScript强烈建议选择“Yes”。TypeScript能为大型项目提供强大的类型支持Vue3本身也是用TS编写的生态支持极好。即使你是新手从开始就接触TS也是利大于弊。是否添加JSX支持如果你熟悉React或需要更灵活的模板渲染可以选上。对于大多数使用单文件组件.vue的场景可以先不选。是否添加Vue Router用于单页面应用的路由管理根据项目需要选择。是否添加Pinia这是Vue3官方推荐的状态管理库替代了Vuex。对于需要跨组件共享状态的场景建议选上。是否添加Vitest一个基于Vite的单元测试框架。可根据项目测试需求选择。是否添加E2E测试端到端测试如Cypress或Playwright通常在大中型项目中使用。是否添加ESLint/Prettier代码规范和格式化工具体系。建议选上有助于保持团队代码风格一致。安装依赖并运行 配置完成后按照提示进入项目目录安装依赖并启动。cd my-vite-vue3-app npm install npm run dev # 或使用 pnpm/yarn pnpm install pnpm devVite的启动速度会明显快于Vue CLI。启动后访问控制台输出的地址通常是http://localhost:5173同样能看到欢迎页面。Vite创建方式的特点与心得优点开发服务器启动和热更新速度极快体验上有质的提升。配置更简洁vite.config.ts基于ESM的设计更现代。生产构建使用Rollup打包效率高。缺点生态虽然增长迅速但某些非常古老的、针对Webpack特定写法的插件或库可能需要寻找替代品或额外配置。对于深度定制构建流程需要学习Rollup/Vite的插件体系。实操心得对于所有全新的Vue3项目我个人毫无保留地推荐Vite。它的速度优势能显著提升开发幸福感。而且其设计理念更贴合现代前端发展趋势。你可能会遇到一些关于“error [ERR_MODULE_NOT_FOUND]: cannot find package vite imported from”的错误这通常是因为依赖没有正确安装或者Node版本过低请确保在项目根目录执行了npm install并检查Node版本。2.4 两种方式如何选择一张表说清楚为了让你更直观地做出选择我把核心差异整理成了下表特性维度Vue CLI (基于 Webpack)Vite (基于 ESM Rollup)选择建议启动速度较慢需要打包依赖极快原生ESM按需加载追求开发效率选Vite热更新(HMR)速度尚可项目大时变慢速度极快几乎无感追求流畅体验选Vite配置复杂度较高Webpack配置较低更声明式新手或喜欢简洁选Vite生态成熟度极高插件海量高增长快主流库已支持需要特定老旧插件选Vue CLI构建输出优化成熟可控性强优化好Tree-shaking更高效两者生产构建都优秀学习曲线需了解Webpack需了解ESM和Rollup概念Vite概念更现代入门可能更简单最佳场景Vue2升级、复杂历史配置项目、团队技术栈固化全新Vue3项目、追求极致开发体验、现代技术栈我的结论是除非你有明确的、必须使用Vue CLI的理由如遗留配置迁移否则请直接使用Vite。它代表了前端工具链的未来方向。3. 项目骨架核心源码深度解读无论你用哪种方式创建了项目打开项目文件夹你会看到一套相似的文件结构。很多初学者会直接跳到src/components里写页面但理解项目的入口和根组件是掌握整个应用生命周期的关键。我们来逐一拆解最重要的几个文件。3.1 入口文件main.ts的职责与演变main.ts如果没选TypeScript则是main.js是整个Vue应用的启动入口。它的代码非常精简但每一行都至关重要。// 1. 导入 createApp 工厂函数 import { createApp } from vue // 2. 导入根组件 import App from ./App.vue // 3. 导入全局样式可选 import ./style.css // 4. 创建应用实例 const app createApp(App) // 5. 可选在这里可以进行一些全局配置 // 例如注册全局组件、自定义指令、插件等 // app.component(MyGlobalComponent, MyGlobalComponent) // app.directive(focus, focusDirective) // app.use(router) // app.use(pinia) // 6. 将应用实例挂载到DOM元素上 app.mount(#app)逐行深度解析import { createApp } from vue这是Vue3的核心变化之一。在Vue2中我们通过new Vue()来创建根实例。Vue3引入了createApp这个工厂函数它返回一个应用实例app instance。这样做的好处是应用实例之间相互隔离避免了Vue2中全局配置如Vue.component,Vue.directive污染所有测试用例或微前端子应用的问题。import App from ./App.vue导入我们定义的根组件。在Vue中一切皆是组件整个应用就是一棵以App.vue为根节点的组件树。import ./style.css导入全局样式。Vite对CSS有原生支持这里导入后样式会对整个应用生效。const app createApp(App)调用createApp函数传入根组件App创建出应用实例app。此时应用实例已经创建但还没有被渲染到页面上。应用实例配置在app.mount()之前我们可以对app实例进行一系列全局配置。这是Vue3应用级API的主要舞台。app.component(): 注册全局组件这样在任何子组件中都可以直接使用无需再import。app.directive(): 注册全局自定义指令。app.use(): 安装插件例如routerVue Router、pinia状态管理等。插件可以扩展应用的能力。app.mixin(): 全局混入谨慎使用在Vue3 Composition API下混入的使用场景已大大减少。app.config.globalProperties: 添加全局属性可以在任何组件实例中通过this访问在Composition API的setup中需通过getCurrentInstance()获取。重要提示Vue3的全局API改动其设计目的就是为了更好的“树摇”Tree-shaking和代码组织。那些你不在应用中使用的全局API如Vue.nextTick最终不会被打包进生产环境的代码中减小了打包体积。app.mount(#app)这是启动应用的“点火”命令。它告诉Vue将我们创建的应用实例挂载到HTML页面中id为app的DOM元素上。这个#app元素通常位于项目根目录的index.html文件中。与Vue2的对比与心得在Vue2中入口文件可能是这样的import Vue from vue import App from ./App.vue new Vue({ render: h h(App), }).$mount(#app)最大的区别就是从new Vue()变成了createApp()。这个改变看似微小但解决了Vue2在大型应用和测试中的一些顽疾。在实际开发中尤其是在配置全局错误处理器(app.config.errorHandler)或性能追踪(app.config.performance)时你会体会到这种实例隔离带来的好处——配置只对当前应用生效不会影响其他可能共存的Vue应用。3.2 根组件App.vue的结构与逻辑起点App.vue是我们应用的根组件是所有其他组件的容器。Vite创建的项目模板提供了一个非常标准的示例。script setup langts // 1. 使用 script setup 语法糖 import { ref } from vue // 2. 导入子组件 import HelloWorld from ./components/HelloWorld.vue // 3. 导入图片等静态资源Vite特有方式 import vueLogo from ./assets/vue.svg // 4. 使用Composition API定义响应式数据 const count ref(0) /script template div !-- 5. 使用导入的图片 -- a hrefhttps://vitejs.dev target_blank img src/vite.svg classlogo altVite logo / /a a hrefhttps://vuejs.org/ target_blank img :srcvueLogo classlogo vue altVue logo / /a /div !-- 6. 使用子组件并传递数据 -- HelloWorld msgVite Vue / !-- 7. 绑定事件与响应式数据 -- div classcard button typebutton clickcountcount is {{ count }}/button p Edit codecomponents/HelloWorld.vue/code to test HMR /p /div p classread-the-docs Click on the Vite and Vue logos to learn more /p /template style scoped /* 8. 使用 scoped 作用域样式 */ .logo { height: 6em; padding: 1.5em; will-change: filter; transition: filter 300ms; } .logo:hover { filter: drop-shadow(0 0 2em #646cffaa); } .logo.vue:hover { filter: drop-shadow(0 0 2em #42b883aa); } /style核心要点拆解script setup langts这是Vue3单文件组件(SFC)的“语法糖”是Composition API的一种更简洁的写法。在script setup中声明的顶层变量、函数、import导入都可以直接在模板中使用无需通过return暴露。langts表明我们使用TypeScript。导入与响应式数据import { ref } from vue导入了ref函数用于创建响应式的数据。const count ref(0)创建了一个响应式引用初始值为0。在模板中我们通过{{ count }}来显示它通过clickcount来修改它。修改后视图会自动更新。静态资源处理import vueLogo from ./assets/vue.svg是Vite处理静态资源的方式。它会将资源解析为公共URL你可以像使用变量一样在模板中绑定它:srcvueLogo。而img src/vite.svg ...中的/vite.svgVite会将其视为位于public目录下的静态文件直接复制到输出目录不经过构建处理。组件使用与Props传递HelloWorld msgVite Vue /使用了导入的HelloWorld子组件并通过msg属性Prop向其传递了一个字符串。在子组件中需要使用defineProps来接收这个值。样式作用域style scoped中的scoped属性是Vue SFC的核心特性之一。它通过给本组件的HTML元素和CSS选择器添加唯一的>import { defineConfig } from vite import vue from vitejs/plugin-vue // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], })这是Vite的配置文件极其简洁。defineConfig提供了类型提示。plugins数组用于配置Vite插件vitejs/plugin-vue是官方插件用于解析.vue单文件组件。随着项目复杂你可能会在这里配置别名resolve.alias、代理服务器server.proxy等。vue.config.js- Vue CLI的核心配置如果使用Vue CLIVue CLI的项目根目录下可能会有这个文件用于覆盖和扩展Webpack配置。它的配置项更复杂但能力也更强。4. 从入门到实践编写你的第一个Vue3组件理解了项目骨架我们来动手写一个简单的组件串联起核心概念。我们将创建一个UserCard.vue组件展示用户信息并可以点击关注。4.1 组件创建与基础结构在src/components目录下新建文件UserCard.vue。script setup langts // 1. 使用 defineProps 定义组件接收的属性 interface Props { name: string bio?: string // 可选属性 initialFollowed?: boolean } const props withDefaults(definePropsProps(), { bio: 暂无简介, initialFollowed: false }) // 2. 使用 defineEmits 定义组件发出的事件 const emit defineEmits{ follow: [id: number] // 事件名: [参数类型] }() // 3. 使用 ref 和 reactive 定义响应式状态 import { ref, reactive, computed } from vue const isFollowed ref(props.initialFollowed) const userStats reactive({ posts: 42, followers: 1000, following: 120 }) // 4. 使用 computed 定义计算属性 const followerText computed(() { return isFollowed.value ? 已关注 : 关注 }) // 5. 定义方法 function toggleFollow() { isFollowed.value !isFollowed.value // 触发自定义事件并传递一个模拟的用户ID emit(follow, 1) } /script template div classuser-card h2{{ name }}/h2 p classbio{{ bio }}/p div classstats span动态: {{ userStats.posts }}/span span粉丝: {{ userStats.followers }}/span span关注: {{ userStats.following }}/span /div button clicktoggleFollow :class{ followed: isFollowed } {{ followerText }} /button /div /template style scoped .user-card { border: 1px solid #ccc; border-radius: 8px; padding: 20px; max-width: 300px; margin: 10px; } .bio { color: #666; font-size: 0.9em; } .stats { display: flex; justify-content: space-between; margin: 15px 0; font-size: 0.8em; color: #888; } button { padding: 8px 16px; background-color: #42b883; color: white; border: none; border-radius: 4px; cursor: pointer; width: 100%; } button.followed { background-color: #ccc; color: #333; } /style4.2 在App.vue中使用组件修改src/App.vue引入并使用我们新建的组件。script setup langts import { ref } from vue import UserCard from ./components/UserCard.vue const userName ref(前端达人) const userBio ref(热爱Vue3与前沿技术分享实战干货。) // 处理子组件发出的事件 function handleFollow(userId: number) { console.log(用户ID ${userId} 的关注状态发生了变化) // 这里可以执行实际的关注/取消关注API调用 } /script template div h1我的第一个Vue3组件/h1 !-- 使用组件并传递props监听事件 -- UserCard :nameuserName :biouserBio followhandleFollow / !-- 可以复用多个 -- UserCard name另一位开发者 initialFollowed followhandleFollow / /div /template4.3 核心概念实操解析通过这个简单组件我们实践了Vue3的几个核心概念defineProps与defineEmits在script setup中我们使用这两个编译器宏来定义组件的对外接口。它们提供了完整的TypeScript类型支持是组件间通信的基石。withDefaults用于为可选Props提供默认值。ref与reactiveref用于定义基本类型如string,number,boolean或任何类型的响应式引用。在脚本中访问和修改其值需要使用.value在模板中会自动解包无需.value。例子isFollowed。reactive用于定义对象类型的响应式代理。直接访问和修改其属性即可。例子userStats。选择心得我个人的习惯是对于基本类型或将来可能被重新赋值的引用如一个可能被替换的对象或数组用ref对于一个确定结构的、属性会频繁交互的响应式对象用reactive。当不确定时用ref更保险。computed用于创建依赖于其他响应式状态的计算属性。它会缓存计算结果只有依赖项变化时才会重新计算。例子中followerText依赖于isFollowed。模板语法与事件处理{{ }}插值:绑定属性v-bind的缩写绑定事件v-on的缩写。在模板中可以直接使用在script setup中定义的变量和方法。样式作用域style scoped确保了本组件的样式不会影响其他地方的button或.user-card类。运行项目你将在页面上看到两个用户卡片点击按钮可以切换关注状态并在控制台看到事件触发的日志。这个简单的流程涵盖了Vue3组件开发的大部分基础模式。5. 开发与构建流程、优化与问题排查掌握了组件编写我们来看看项目的日常开发流程和如何将其变为可部署的产品。5.1 开发服务器与热更新HMR无论是Vite还是Vue CLI执行npm run dev或npm run serve后启动的就是开发服务器。Vite的开发服务器基于原生ESM启动速度极快。当你修改文件并保存时Vite的HMR热模块替换会精准地更新你修改的模块而无需刷新整个页面状态如count的值得以保留开发体验丝滑。Vue CLI的开发服务器基于Webpack Dev Server同样支持HMR但在大型项目中启动和热更新速度可能慢于Vite。开发小技巧你可以通过package.json中的scripts配置或命令行参数修改开发服务器的端口和主机。例如在vite.config.ts中export default defineConfig({ server: { port: 3000, // 指定端口 host: true, // 监听所有地址方便局域网内手机预览 open: true // 启动后自动打开浏览器 }, // ...其他配置 })5.2 生产环境构建当代码开发完成需要部署时运行构建命令npm run build这个命令会做以下几件事代码转换与打包将Vue SFC、TypeScript/JavaScript模块、CSS等资源进行编译、转换、压缩和打包。Tree-shaking移除未被使用的代码Dead Code显著减小打包体积。Vue3的API设计和Vite/Rollup的配合使得Tree-shaking效果非常好。资源处理图片、字体等资源会被处理并输出到dist或build目录通常会被压缩并生成哈希文件名用于长效缓存。代码分割现代构建工具会自动进行代码分割将不同路由或异步组件打包成独立的文件实现按需加载优化首屏速度。构建完成后你会得到一个dist文件夹里面就是静态文件可以直接部署到任何静态文件服务器如Nginx、Apache、Vercel、Netlify等。5.3 常见问题与排查实录在实际开发中你一定会遇到各种问题。这里记录几个高频问题及其解决思路。问题1启动或安装依赖时报错error [ERR_MODULE_NOT_FOUND]: cannot find package vite imported from原因这通常是因为node_modules依赖安装不完整或损坏或者全局与本地Vite版本冲突。解决删除项目根目录下的node_modules文件夹和package-lock.json或yarn.lock、pnpm-lock.yaml。清除npm缓存npm cache clean --force。重新安装依赖npm install或yarn/pnpm install。确保你的Node.js版本符合要求16.0.0。问题2组件引入后模板中无法识别或报类型错误原因在TypeScript项目中Vue SFC可能需要类型声明或者组件路径引入错误。解决检查导入路径是否正确。对于VolarVue的官方VSCode扩展用户确保在.vue文件中使用了script setup langts并且项目根目录下有正确的tsconfig.json。Vite创建的项目已经配置好了。如果是从.js文件迁移到.ts可能需要重启TypeScript语言服务在VSCode中按CtrlShiftP输入Restart TS Server。问题3响应式数据更新了但视图没有更新原因这是Vue3响应式系统最常见的坑。通常是因为直接修改了reactive对象的某个属性为一个非响应式的新对象或者没有通过.value来修改ref的值。解决对于ref确保在.js/.ts逻辑中修改时使用了.value。对于reactive避免整个属性被重新赋值。如果需要替换数组可以使用array.splice或使用ref包裹数组。使用Vue Devtools检查数据状态确认数据是否真的变成了响应式。问题4生产构建后资源路径404尤其是路由为History模式时原因静态资源路径配置不正确或服务器未配置SPA回退。解决在vite.config.ts中可以配置base选项为你的子路径如果部署在非根目录。export default defineConfig({ base: /my-app/, // 如果你部署在 https://example.com/my-app/ // ... })如果使用Vue Router的History模式部署到传统静态服务器如Nginx时需要配置一个回退规则将所有非静态文件请求重定向到index.html。# Nginx 配置示例 location / { try_files $uri $uri/ /index.html; }问题5ESLint或Prettier报错与团队格式不一致原因代码风格检查工具配置不一致。解决项目根目录下应该有.eslintrc.cjs、.prettierrc等配置文件。确保团队使用相同的配置。可以在VSCode中安装ESLint和Prettier扩展并设置保存时自动格式化。对于某些无法自动修复的规则可以在代码行上方使用注释// eslint-disable-next-line rule-name临时禁用但应谨慎使用。掌握这些常见问题的排查方法能让你在开发过程中更加从容。记住遇到问题首先看控制台报错信息大部分错误信息都已经非常明确其次善用Vue Devtools和浏览器开发者工具最后搜索引擎和Vue官方文档、GitHub Issues是你的强大后援。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价