十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Vue3 零基础极速入门:2小时实战构建完整SPA应用

Vue3 零基础极速入门:2小时实战构建完整SPA应用 这次我们来看一个面向零基础开发者的 Vue3 快速入门实战项目。如果你之前接触过 Vue2 或者完全没碰过 Vue想用最短的时间上手 Vue3 并做出一个能跑起来的项目这篇文章就是为你准备的。这个项目的核心不是讲深奥的原理而是提供一个“即学即用”的极简路径让你在 2 小时内完成从环境搭建到项目上线的全过程并附带了完整的源码用于对照和二次开发。Vue3 作为当前主流的前端框架其组合式 API、更好的 TypeScript 支持以及更高的性能已经成为新项目的首选。但对于初学者或需要快速切入的开发者来说官方文档虽然详尽但内容庞杂容易让人迷失在概念中。本文的目标就是帮你绕过那些复杂的理论直接聚焦于“如何用 Vue3 做出一个东西”。我们会重点关注环境配置、项目创建、核心 API 的实战应用、组件开发以及最终的构建部署确保每一步都有明确的代码和可验证的结果。1. 核心能力速览在开始动手之前我们先快速了解这个“2小时速成”计划能带你完成什么以及你需要准备什么。能力项说明目标读者零基础前端新手、Vue2 转 Vue3 的开发者、需要快速验证想法或搭建原型的技术人员。技术栈Vue3 Vite TypeScript (可选) Pinia (状态管理) Vue Router (路由)。硬件/环境门槛一台能联网的电脑Windows/macOS/Linux均可无需高性能显卡对内存和CPU无特殊要求。核心产出一个具备基础功能如数据展示、表单交互、路由跳转、状态管理的完整单页应用SPA。学习方式实战驱动即写即看效果避免纯理论讲解。源码与资源提供完整的项目源码、配置文件和关键步骤的代码片段可直接运行和修改。最终验证本地开发服务器运行成功并能执行生产构建生成可部署的静态文件。2. 适用场景与使用边界这个速成方案非常适合以下几种场景技术选型验证团队评估 Vue3 是否适合新项目需要快速搭建一个演示 Demo。个人技能提升前端开发者希望系统性地、高效地掌握 Vue3 的核心开发模式。教学与分享为内部培训或技术分享准备一个结构清晰、可运行的案例。原型开发在构思新产品或功能时需要快速构建一个可交互的前端界面原型。需要注意的边界非企业级脚手架本文项目结构是极简和教学导向的不同于vue-cli或企业内部复杂的脚手架但核心概念完全一致。深度优化有限为了聚焦核心不会深入探讨 Webpack/Vite 的高级配置、服务端渲染SSR、微前端等高级主题。UI 库依赖为了更纯粹地理解 Vue3示例主要使用原生 HTML/CSS 和少量 Element Plus 组件不会深入某个特定 UI 库。安全与合规最终构建的静态资源可部署于任何静态托管服务。若涉及后端 API 调用需自行处理跨域、鉴权等安全问题。3. 环境准备与前置条件工欲善其事必先利其器。在开始编码前请确保你的开发环境已就绪。3.1 基础软件检查请按顺序安装和检查以下工具这是 Vue3 开发的基石。Node.js 与 npmVue3 的构建和依赖管理都依赖于 Node.js。请访问 Node.js 官网 下载并安装LTS长期支持版。安装完成后打开终端Windows 的 CMD/PowerShellmacOS/Linux 的 Terminal输入以下命令验证node -v npm -v如果正确显示版本号例如v18.x.x和9.x.x说明安装成功。建议 Node.js 版本 16.0.0。代码编辑器推荐使用Visual Studio Code (VS Code)它拥有强大的 Vue 和 TypeScript 生态插件。前往 VS Code 官网 下载安装。浏览器开发者工具现代浏览器如 Chrome、Edge、Firefox内置的开发者工具是调试 Vue 应用的利器请确保你会使用其“元素Elements”和“控制台Console”面板。3.2 VS Code 推荐插件安装以下插件可以极大提升 Vue3 开发体验和效率。在 VS Code 的扩展商店中搜索并安装VolarVue3 官方推荐的语言支持插件取代了之前的 Vetur。提供语法高亮、智能提示、类型检查等。TypeScript Vue Plugin (Volar)如果你使用 TypeScript这个插件能提供更好的 TS 支持。ESLint代码风格和质量检查工具。Prettier代码格式化工具。建议配置保存时自动格式化。Auto Rename Tag自动重命名配对的 HTML/XML 标签。Path Intellisense路径自动补全。3.3 项目目录规划在开始前建议在本地创建一个清晰的工作目录例如D:\Projects\vue3-crash-course或~/Projects/vue3-crash-course。所有后续操作都将在这个目录下进行。4. 项目创建与初始化我们将使用Vite作为构建工具它比传统的vue-cli启动更快配置更简单是 Vue 官方推荐的新一代前端工具链。4.1 使用 Vite 创建 Vue3 项目打开终端进入你准备好的工作目录执行以下命令# 使用 npm 创建项目项目名设为 vue3-quick-start npm create vuelatest vue3-quick-start执行命令后你会看到一个交互式的命令行界面用于选择项目特性。4.2 特性选择指南面对一系列选项请按照以下推荐进行选择这符合我们“极简、即用”的目标Add TypeScript?Yes推荐选择 YesTypeScript 能提供更好的类型安全和开发体验即使你是新手从 TS 开始也是好习惯Add JSX Support?NoJSX 是可选的我们先使用 Vue 的单文件组件语法Add Vue Router for Single Page Application?Yes路由是单页应用的核心必须选Add Pinia for state management?YesPinia 是 Vue3 官方推荐的状态管理库比 Vuex 更简单推荐选择Add Vitest for Unit Testing?No速成阶段可跳过单元测试Add an End-to-End Testing Solution?No速成阶段可跳过 E2E 测试Add ESLint for code quality?Yes代码规范检查建议选择Add Prettier for code formatting?Yes代码自动格式化建议选择选择完成后Vite 会自动创建项目并安装初始依赖。这个过程可能需要几分钟取决于你的网络速度。4.3 安装依赖并启动项目创建完成后进入项目目录并安装依赖cd vue3-quick-start npm install依赖安装完成后运行开发服务器npm run dev终端会输出类似Local: http://localhost:5173/的信息。打开浏览器访问这个地址你应该能看到 Vue 的默认欢迎页面。恭喜你的第一个 Vue3 项目已经成功运行起来了5. 核心概念实战组合式 APIVue3 最大的变化之一是引入了组合式 API (Composition API)。我们通过修改默认的App.vue和创建一个新组件来快速掌握它。5.1 响应式数据 (ref与reactive)打开src/App.vue文件将其内容替换为以下代码template div classapp-container h1{{ title }}/h1 p计数器: {{ count }}/p button clickincrement点我加1/button button clickdecrement :disabledcount 0点我减1/button hr / h2用户信息/h2 p姓名: {{ user.name }}/p p年龄: {{ user.age }}/p input v-modeluser.name placeholder修改姓名 / button clickuser.age年龄1/button hr / h2待办事项 ({{ todos.length }})/h2 input v-modelnewTodo keyup.enteraddTodo placeholder输入后按回车添加 / ul li v-for(todo, index) in todos :keyindex {{ todo.text }} button clickremoveTodo(index)删除/button /li /ul /div /template script setup langts // 1. 导入必要的函数 import { ref, reactive } from vue // 2. 使用 ref 定义响应式基本类型数据 const title ref(Vue3 极简速成实战) const count ref(0) // 3. 使用 reactive 定义响应式对象 const user reactive({ name: 张三, age: 25 }) // 4. 响应式数组 interface TodoItem { text: string } const todos reactiveTodoItem[]([ { text: 学习组合式 API }, { text: 编写一个组件 }, { text: 理解 Pinia 状态管理 } ]) const newTodo ref() // 5. 定义方法函数 function increment() { count.value // 注意ref 定义的值需要通过 .value 访问 } function decrement() { if (count.value 0) { count.value-- } } function addTodo() { if (newTodo.value.trim()) { todos.push({ text: newTodo.value }) newTodo.value // 清空输入框 } } function removeTodo(index: number) { todos.splice(index, 1) } /script style scoped .app-container { padding: 20px; font-family: sans-serif; } button { margin: 5px; padding: 8px 16px; cursor: pointer; } input { margin: 5px; padding: 8px; } ul { list-style: none; padding-left: 0; } li { margin: 5px 0; padding: 8px; background-color: #f5f5f5; display: flex; justify-content: space-between; align-items: center; } /style代码解析与效果验证script setup这是组合式 API 的语法糖让代码更简洁。所有顶层的绑定变量、函数都能直接在模板中使用。ref用于定义响应式的基本类型数据如字符串、数字、布尔值。在 JS/TS 中访问和修改需要使用.value但在模板中会自动解包直接使用{{ count }}。reactive用于定义响应式的对象或数组。修改其属性或数组元素视图会自动更新。v-model双向数据绑定指令常用于表单输入元素。click、keyup.enter事件监听指令。v-for列表渲染指令。保存文件后浏览器页面会自动热更新。尝试点击按钮、修改输入框观察数据的变化和视图的更新。这涵盖了 Vue3 最核心的响应式系统和模板语法。5.2 计算属性与侦听器 (computed与watch)计算属性和侦听器是处理衍生数据和副作用的重要工具。我们在App.vue的script setup部分继续添加// 在原有导入基础上增加 computed 和 watch import { ref, reactive, computed, watch } from vue // ... 之前的 ref 和 reactive 数据 ... // 6. 计算属性基于现有状态计算出新的值 const doubleCount computed(() count.value * 2) const isAdult computed(() user.age 18) const todoSummary computed(() { const total todos.length const done 0 // 假设没有完成状态这里只是演示 return 总计 ${total} 项已完成 ${done} 项 }) // 7. 侦听器观察响应式数据的变化并执行副作用 // 侦听单个 ref watch(count, (newValue, oldValue) { console.log(计数器从 ${oldValue} 变为 ${newValue}) }) // 侦听 reactive 对象的某个属性 watch( () user.age, (newAge) { console.log(用户年龄变为: ${newAge}) if (newAge 30) { alert(恭喜步入中年) // 副作用示例 } } ) // 侦听多个数据源 watch([count, () user.name], ([newCount, newName], [oldCount, oldName]) { console.log(计数或姓名发生了变化: count${newCount}, name${newName}) })然后在模板中展示计算属性的结果template !-- ... 之前的模板内容 ... -- hr / h2计算属性与侦听器/h2 p双倍计数: {{ doubleCount }}/p p是否成年: {{ isAdult ? 是 : 否 }}/p p待办摘要: {{ todoSummary }}/p /template保存后操作计数器或修改年龄观察浏览器控制台F12打开的输出理解watch是如何工作的。6. 组件化开发实战组件化是 Vue 的核心思想。我们来创建一个独立的组件并在父组件中使用它。6.1 创建子组件在src/components目录下新建一个文件TodoItem.vuetemplate div classtodo-item :class{ completed: props.todo.completed } input typecheckbox :checkedprops.todo.completed changeemit(toggle) / span classtodo-text{{ props.todo.text }}/span button clickemit(delete)删除/button /div /template script setup langts // 定义组件接收的 Props interface Todo { text: string completed: boolean } const props defineProps{ todo: Todo }() // 定义组件可以触发的事件 const emit defineEmits{ toggle: [] delete: [] }() /script style scoped .todo-item { display: flex; align-items: center; padding: 10px; margin: 5px 0; border: 1px solid #ddd; border-radius: 4px; } .todo-item.completed .todo-text { text-decoration: line-through; color: #888; } .todo-text { flex-grow: 1; margin-left: 10px; } button { margin-left: 10px; } /style6.2 在父组件中使用子组件修改src/App.vue引入并使用我们新建的TodoItem组件template div classapp-container !-- ... 保留之前的模板内容 ... -- hr / h2组件化待办列表/h2 div v-for(item, index) in componentTodos :keyitem.id !-- 使用 TodoItem 组件 -- TodoItem :todoitem toggletoggleTodo(index) deletedeleteTodo(index) / /div input v-modelnewComponentTodo keyup.enteraddComponentTodo placeholder添加组件化待办 / /div /template script setup langts // 导入子组件 import TodoItem from ./components/TodoItem.vue import { ref, reactive } from vue // ... 保留之前的响应式数据 ... // 为组件化示例准备的数据 interface ComponentTodo { id: number text: string completed: boolean } const componentTodos reactiveComponentTodo[]([ { id: 1, text: 学习组件通信, completed: false }, { id: 2, text: 掌握 Props 和 Emits, completed: true }, ]) const newComponentTodo ref() let nextId 3 function addComponentTodo() { if (newComponentTodo.value.trim()) { componentTodos.push({ id: nextId, text: newComponentTodo.value, completed: false, }) newComponentTodo.value } } function toggleTodo(index: number) { componentTodos[index].completed !componentTodos[index].completed } function deleteTodo(index: number) { componentTodos.splice(index, 1) } /script !-- 样式部分保持不变 --关键点解析defineProps使用 TypeScript 泛型语法定义组件接收的属性提供了完美的类型提示。defineEmits定义组件可以向上触发的自定义事件。父组件通过:todoitem传递数据Props 下行通过toggletoggleTodo监听事件Events 上行。子组件通过emit(toggle)触发事件。保存所有文件浏览器中应该能看到一个更结构化的待办列表可以勾选完成状态和删除项目。这演示了 Vue3 组件间通信的标准模式。7. 路由与状态管理实战一个完整的应用离不开路由跳转和全局状态管理。我们已经安装了 Vue Router 和 Pinia现在来使用它们。7.1 配置与使用 Vue RouterVite 创建项目时已经生成了路由配置。查看src/router/index.ts可以看到默认路由。我们修改src/views/AboutView.vue和src/views/HomeView.vue来创建更实用的页面。修改src/views/HomeView.vuetemplate div classhome h1首页/h1 p这是应用的主页面展示了全局计数器的状态。/p pPinia 全局计数: {{ mainStore.count }}/p button clickmainStore.increment增加全局计数/button button clickmainStore.reset重置全局计数/button hr / router-link to/about跳转到关于页面/router-link | router-link to/user/123查看用户 123/router-link /div /template script setup langts import { useMainStore } from /stores/main const mainStore useMainStore() /script修改src/views/AboutView.vuetemplate div classabout h1关于我们/h1 p这个页面展示了路由参数和编程式导航。/p p当前路径: {{ $route.fullPath }}/p button clickgoBack返回首页/button /div /template script setup langts import { useRouter } from vue-router const router useRouter() function goBack() { // 编程式导航 router.push(/) } /script添加一个带参数的路由修改src/router/index.ts在routes数组中添加const routes: ArrayRouteRecordRaw [ // ... 已有的 home 和 about 路由 ... { path: /user/:id, name: user, component: () import(../views/UserView.vue), // 懒加载 }, ]然后创建src/views/UserView.vuetemplate div h1用户详情/h1 p用户ID: {{ userId }}/p router-link to/返回首页/router-link /div /template script setup langts import { useRoute } from vue-router import { computed } from vue const route useRoute() // 使用计算属性获取路由参数 const userId computed(() route.params.id as string) /script7.2 配置与使用 Pinia 状态管理Pinia 的用法非常直观。首先查看src/stores目录应该已有一个counter.ts。我们创建一个更综合的main.ts来管理全局状态。创建src/stores/main.tsimport { ref, computed } from vue import { defineStore } from pinia // 定义并导出 store export const useMainStore defineStore(main, () { // 状态 (state) const count ref(0) const user ref({ name: 全局用户, role: admin }) const todos refArray{ text: string; done: boolean }([]) // 计算属性 (getters) const doubleCount computed(() count.value * 2) const todoCount computed(() todos.value.length) // 动作 (actions) function increment() { count.value } function decrement() { if (count.value 0) count.value-- } function reset() { count.value 0 } function addTodo(text: string) { todos.value.push({ text, done: false }) } function toggleTodo(index: number) { todos.value[index].done !todos.value[index].done } // 返回所有需要在组件中使用的属性和方法 return { count, user, todos, doubleCount, todoCount, increment, decrement, reset, addTodo, toggleTodo, } })在组件中使用 Pinia Store我们已经在上面的HomeView.vue中使用了useMainStore()。在任何组件中你都可以通过这种方式引入并操作全局状态。Pinia 的状态是响应式的修改后会自动更新所有使用它的组件。修改src/App.vue的导航部分为了让路由生效我们需要修改App.vue使用router-view来显示当前路由对应的页面组件并使用router-link进行导航。template div idapp nav router-link to/首页/router-link | router-link to/about关于/router-link | span全局状态示例: {{ mainStore.count }}/span /nav !-- 路由出口匹配的组件将渲染在这里 -- router-view / !-- 我们之前的练习内容可以放在这里或者注释掉 -- !-- div classapp-container ... /div -- /div /template script setup langts import { useMainStore } from /stores/main const mainStore useMainStore() /script style #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } nav { padding: 30px; } nav a { font-weight: bold; color: #2c3e50; margin: 0 10px; } nav a.router-link-exact-active { color: #42b983; } /style现在你的应用已经具备了完整的路由导航和全局状态管理能力。点击导航链接页面内容会切换并且首页的计数器状态是全局共享的。8. 项目构建与部署开发完成后我们需要将代码构建成适合生产环境部署的静态文件。8.1 生产环境构建在项目根目录下运行构建命令npm run buildVite 会将你的项目进行打包、压缩、代码分割等优化并将结果输出到dist目录。这个过程可能会需要一些时间。8.2 预览生产版本构建完成后你可以使用 Vite 提供的预览命令在本地模拟生产环境查看效果npm run preview访问终端输出的本地地址通常是http://localhost:4173检查应用是否一切正常。预览模式有助于发现一些仅在生产构建中出现的问题。8.3 部署静态文件dist目录下的所有文件都是静态资源HTML, JS, CSS, 图片等你可以将其部署到任何静态网站托管服务上例如GitHub Pages: 免费适合个人项目展示。Vercel / Netlify: 提供自动化部署、CDN、自定义域名等对前端项目非常友好。阿里云/腾讯云对象存储 (OSS/COS): 配置 Bucket 为静态网站托管即可。自有服务器: 使用 Nginx 或 Apache 配置一个虚拟主机来服务dist目录。部署的核心步骤就是将dist文件夹的全部内容上传到托管服务的指定位置。9. 常见问题与排查方法在学习和实践过程中你可能会遇到以下问题问题现象可能原因排查方式解决方案npm install失败网络错误或超时1. 网络连接问题2. npm 源访问慢1. 检查网络2. 运行npm config get registry查看源1. 切换 npm 镜像源npm config set registry https://registry.npmmirror.com2. 使用yarn或pnpmnpm run dev无法启动端口被占用默认端口 5173 已被其他程序使用查看终端错误信息确认端口冲突1. 终止占用端口的进程2. 在vite.config.ts中配置server.port为其他端口页面空白控制台报Failed to resolve import1. 组件导入路径错误2. TypeScript 路径别名未配置1. 检查import语句的路径2. 检查tsconfig.json中的paths配置1. 使用相对路径./或别名/2. 确保vite.config.ts中正确配置了resolve.alias修改代码后页面没有热更新 (HMR)1. 文件保存未触发2. 某些配置可能导致 HMR 失效1. 检查编辑器自动保存设置2. 查看浏览器控制台和终端有无错误1. 手动保存文件2. 尝试重启开发服务器npm run dev生产构建后页面资源加载 404 (路由为 history 模式)服务器未配置 SPA 回退直接访问非根路由如/about报 404在服务器配置中将所有非静态文件请求重定向到index.html(Nginx:try_files $uri $uri/ /index.html;)TypeScript 类型报错但运行正常1. 类型定义不完整2. 第三方库未安装类型包查看 VS Code 问题面板或终端tsc输出1. 安装对应的types/包如npm install -D types/node2. 在*.d.ts文件中声明模块Pinia store 在组件外无法使用在setup()生命周期之外调用useStore()检查调用useStore()的时机和位置Pinia store 必须在setup()(或script setup) 或生命周期钩子函数内部调用10. 最佳实践与下一步建议通过以上步骤你已经完成了一个 Vue3 应用的完整开发流程。为了写出更健壮、可维护的代码请记住以下建议关注官方文档Vue3、Vite、Pinia、Vue Router 都有优秀的官方文档遇到问题时首先查阅。善用开发者工具安装浏览器 Vue Devtools 扩展它可以帮你直观地检查组件树、状态、事件是调试神器。代码组织对于复杂组件可以使用 Composable组合式函数来抽离和复用逻辑。将相关的ref、computed、watch、函数组织在一起。类型安全坚持使用 TypeScript并严格定义组件 Props、Emits、Store 状态的类型这能在编码阶段就发现大量潜在错误。状态管理原则不是所有状态都需要放到 Pinia 中。只有需要在多个不相关组件间共享的状态才考虑使用全局 Store。组件内部状态优先使用ref/reactive。性能考量对于大型列表使用v-for时务必提供唯一的:key。对于复杂计算使用computed进行缓存。避免在模板中进行复杂的 JavaScript 运算。下一步学习方向深入响应式系统理解ref、reactive、shallowRef、markRaw等的区别。高级组件模式学习插槽Slots、作用域插槽、动态组件、异步组件、Teleport、Suspense。生态集成学习使用流行的 UI 库如 Element Plus、Ant Design Vue、Vant 等。状态管理进阶学习 Pinia 的插件、持久化存储、服务端渲染 (SSR) 集成。测试为组件和组合式函数编写单元测试 (Vitest) 和端到端测试 (Cypress/Playwright)。工程化学习 Vite 的高级配置、环境变量管理、代码分割、打包优化。这个“2小时速成”项目为你打开了 Vue3 开发的大门。源码已包含所有步骤的完整代码你可以在此基础上不断添加新功能如对接真实 API、实现更复杂的 UI 交互、尝试不同的状态管理场景从而在实践中巩固和深化对 Vue3 的理解。
返回列表