ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Vue3 极速入门:2小时构建响应式待办事项应用

Vue3 极速入门:2小时构建响应式待办事项应用 你是不是也遇到过这样的情况想快速上手 Vue3却被官方文档的庞大体系、各种新概念和复杂的配置劝退网上教程要么是零散的片段要么是动辄几十小时的完整课程学了半天还是不知道如何动手写一个真正的项目。今天这篇文章就是要解决这个痛点。我们不谈复杂的源码解析不搞深奥的响应式原理就聚焦一件事如何在最短的时间内用最少的代码跑通一个 Vue3 项目并理解其核心工作模式。本文承诺只要你跟着步骤走2小时内不仅能理解 Vue3 的核心概念还能亲手搭建一个具备基础交互功能的“待办事项”应用并拿到完整的、可运行的源码。这篇文章的核心判断是对于初学者或从 Vue2 迁移的开发者Vue3 的学习门槛被高估了。其核心的 Composition API、响应式系统和组件化思想完全可以通过一个精心设计的实战项目快速掌握。关键在于要绕过那些初期不必要的“噪音”直接切入最常用、最能产生正反馈的环节。接下来我们将从零开始手把手带你完成环境搭建、项目创建、核心语法学习、组件开发直到最终打包上线。每一步都有清晰的解释和可复制的代码目标是让你“即学即用”。1. 这篇文章真正要解决的问题很多前端新手或 Vue2 开发者对 Vue3 望而却步主要卡在以下几个地方概念繁杂ref、reactive、setup、Composition API、Options API、SFC... 新名词一堆不知道从哪里开始。环境配置复杂Node.js 版本、npm/yarn/pnpm、Vite、Webpack、各种插件光是搭建环境就耗去大量精力。教程与实践脱节看了很多“Hello World”示例但不知道如何组织一个真实的、包含多个组件的页面。对“响应式”理解模糊知道数据变了视图会更新但具体到ref和reactive的区别、如何触发更新就一头雾水。本文将直击这些痛点化繁为简只讲解构建一个应用所必需的、最高频的 20% 的 Vue3 知识让你快速上手。环境一步到位使用 Vue 官方推荐的 Vite 工具它比传统的 Webpack 更快、配置更简单几乎是零配置启动。项目驱动学习我们将构建一个“待办事项清单”(Todo List)应用。这个项目虽小但涵盖了组件定义、数据响应式、事件处理、条件渲染、列表渲染等 Vue3 核心功能。提供完整源码文章每个阶段的代码都是完整的你可以边看边敲也可以直接使用文末提供的完整源码仓库。如果你符合以下情况那么这篇文章就是为你准备的有一定 HTML/CSS/JavaScript 基础想学习前端框架。正在使用 Vue2想快速了解 Vue3 的新特性。被其他 Vue3 教程的深度和广度吓到想找一个快速入门路径。需要一个小型但完整的项目案例作为学习模板或面试作品。2. Vue3 核心概念速览告别困惑在动手之前我们用最直白的语言理解几个核心概念避免后续编码时“知其然不知其所以然”。2.1 Composition API vs Options API这是 Vue3 最大的变化之一但不必恐惧。Options API (Vue2 风格)像填表格一样把data、methods、computed、watch等选项分别写在对象的不同属性里。逻辑分散当组件复杂时维护和阅读会比较困难。Composition API (Vue3 主打)像写普通 JavaScript 函数一样组织代码。你可以把相关的数据、计算属性、方法放在同一个函数作用域内通常在setup函数或script setup中逻辑更聚合复用性更强。简单比喻Options API 像分门别类整理工具箱螺丝放一格扳手放一格Composition API 像为完成一个具体任务修自行车把需要的所有工具螺丝、扳手、润滑油都拿出来放在手边。后者在应对复杂任务时更高效。本文我们将使用script setup语法糖这是 Composition API 更简洁的写法也是目前最推荐的方式。2.2 响应式核心ref和reactiveVue3 的响应式系统是构建应用的基石。ref用于定义基本类型如 string, number, boolean或任何类型的响应式数据。它返回一个带有.value属性的响应式对象。在模板中会自动解包无需写.value。import { ref } from vue; const count ref(0); // 创建响应式数据 console.log(count.value); // 访问值需要 .value count.value; // 修改值reactive用于定义对象类型Object, Array, Map, Set的响应式数据。它返回一个响应式代理对象。import { reactive } from vue; const state reactive({ todos: [], inputText: }); console.log(state.todos); // 直接访问属性 state.todos.push({ id: 1, text: Learn Vue3 }); // 直接修改如何选择一个简单的经验法则单个基本类型值用ref一组相关的数据对象或数组用reactive。在本文的 Todo 应用中我们会同时用到两者。2.3 单文件组件 (SFC)Vue 的核心构建单元。一个.vue文件包含了组件的模板HTML、逻辑JavaScript和样式CSS三者封装在一起。!-- MyComponent.vue -- template !-- 组件的 HTML 结构 -- div{{ message }}/div /template script setup // 组件的 JavaScript 逻辑 (使用 Composition API) import { ref } from vue; const message ref(Hello Vue3!); /script style scoped /* 组件的 CSS 样式scoped 表示只作用于本组件 */ div { color: red; } /stylescript setup中的代码会在每次组件实例创建时执行其顶层绑定变量、函数会自动暴露给模板使用。理解了这些我们就可以开始动手了。3. 环境准备5分钟搞定开发环境工欲善其事必先利其器。Vue3 的开发环境搭建已经变得极其简单。3.1 安装 Node.js 和 npmVue 项目运行在 Node.js 环境中并使用 npm或 yarn/pnpm管理依赖。访问 Node.js 官网 下载并安装LTS长期支持版。安装完成后打开终端Windows 用 CMD 或 PowerShellMac 用 Terminal验证安装node -v npm -v如果能看到版本号如v18.x.x和9.x.x说明安装成功。3.2 创建 Vue3 项目我们将使用Vite来创建项目它速度极快。在终端中进入你打算存放项目的目录例如cd ~/Desktop。运行以下命令创建项目npm create vuelatest这个命令会安装并执行create-vue这是 Vue 官方的项目脚手架工具。命令行会提示你进行一些配置选择Project name:输入你的项目名例如vue3-todo-demo。Add TypeScript?本次入门我们选No。Add JSX Support?选No。Add Vue Router for Single Page Application development?选No本文聚焦核心路由后续再学。Add Pinia for state management?选No状态管理是进阶内容。Add Vitest for Unit Testing?选No。Add an End-to-End Testing Solution?选No。Add ESLint for code quality?选No为了简化可以先跳过。配置完成后进入项目目录并安装依赖cd vue3-todo-demo npm install启动开发服务器npm run dev终端会输出一个本地服务器地址通常是http://localhost:5173。用浏览器打开它你应该能看到 Vue 的欢迎页面。至此一个纯净的 Vue3 项目就创建并运行起来了整个过程可能只需要两三分钟。4. 项目结构解析与清理让我们看看 Vite 为我们生成了什么并清理掉不需要的文件专注于我们的 Todo 应用。vue3-todo-demo/ ├── node_modules/ # 项目依赖包 ├── public/ # 静态资源如图标 │ └── favicon.ico ├── src/ # 源代码目录 │ ├── assets/ # 资源文件如图片、样式 │ │ └── vue.svg │ ├── components/ # 组件目录 │ │ └── HelloWorld.vue │ ├── App.vue # 根组件 │ └── main.js # 应用入口文件 ├── index.html # 页面入口 ├── package.json # 项目配置和依赖 ├── vite.config.js # Vite 配置文件 └── ... (其他配置文件)为了简化我们做以下清理删除src/components/HelloWorld.vue文件。删除src/assets/vue.svg文件。清空src/App.vue文件的内容我们将从头编写。修改src/main.js确保它正确导入我们的App.vue。// src/main.js import { createApp } from vue import App from ./App.vue import ./assets/main.css // 可以保留或删除本文我们用内联样式 createApp(App).mount(#app)清空或简化src/assets/main.css或者直接在组件内写样式。现在我们的src目录下几乎是一张白纸可以开始创作了。5. 核心流程拆解构建 Todo 应用我们将把 Todo 应用拆解为几个核心步骤每一步都对应一个 Vue3 的关键知识点。5.1 步骤一构建根组件 App.vue 的骨架首先在src/App.vue中搭建最基本的组件结构。!-- src/App.vue -- template div classapp header h1Vue3 极简待办清单/h1 p一个即学即用的 Vue3 入门项目/p /header main !-- 待办事项输入区 -- !-- 待办事项列表区 -- !-- 状态统计区 -- /main /div /template script setup // 逻辑代码将在这里编写 /script style /* 基础样式重置 */ * { margin: 0; padding: 0; box-sizing: border-box; font-family: Segoe UI, system-ui, sans-serif; } body { background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); min-height: 100vh; display: flex; justify-content: center; align-items: flex-start; padding: 2rem; } .app { background-color: white; width: 100%; max-width: 600px; margin: 0 auto; padding: 2rem; border-radius: 20px; box-shadow: 0 15px 35px rgba(50, 50, 93, 0.1), 0 5px 15px rgba(0, 0, 0, 0.07); } header { text-align: center; margin-bottom: 2.5rem; padding-bottom: 1.5rem; border-bottom: 2px solid #f0f0f0; } header h1 { color: #2c3e50; font-size: 2.5rem; margin-bottom: 0.5rem; } header p { color: #7f8c8d; font-size: 1.1rem; } /style现在运行npm run dev你应该能看到一个带有标题和样式的空白页面。这确认了我们的基础结构是好的。5.2 步骤二定义响应式数据与添加待办这是 Vue3 响应式系统的首次实战。我们要管理一个待办事项列表和输入框的内容。在script setup中引入ref和reactive并定义数据。在模板中创建输入表单。!-- src/App.vue (更新 script 和 template) -- template div classapp header.../header !-- 头部保持不变 -- main !-- 1. 输入区 -- div classinput-section input typetext v-modelnewTodoText keyup.enteraddTodo placeholder输入待办事项按回车添加... classtodo-input / button clickaddTodo classadd-btn添加/button /div !-- 2. 列表区 (稍后填充) -- !-- 3. 状态区 (稍后填充) -- /main /div /template script setup import { ref, reactive } from vue; // 使用 ref 管理单个输入框的值字符串 const newTodoText ref(); // 使用 reactive 管理待办列表数组及其状态 const todoState reactive({ list: [] // 每一项将是一个对象 { id: number, text: string, completed: boolean } }); // 添加待办事项的方法 function addTodo() { const text newTodoText.value.trim(); if (!text) { alert(请输入待办内容); return; } todoState.list.push({ id: Date.now(), // 用时间戳生成简单ID text: text, completed: false // 默认未完成 }); newTodoText.value ; // 清空输入框 } /script style /* 新增输入区样式 */ .input-section { display: flex; gap: 10px; margin-bottom: 2rem; } .todo-input { flex: 1; padding: 15px 20px; border: 2px solid #e0e0e0; border-radius: 12px; font-size: 1rem; transition: border-color 0.3s; } .todo-input:focus { outline: none; border-color: #3498db; } .add-btn { padding: 0 25px; background-color: #2ecc71; color: white; border: none; border-radius: 12px; font-size: 1rem; font-weight: bold; cursor: pointer; transition: background-color 0.3s; } .add-btn:hover { background-color: #27ae60; } /style关键点解析v-modelnewTodoText这是 Vue 的双向数据绑定指令。它将输入框的值与newTodoText这个ref变量同步。输入框内容变化变量值自动更新修改变量值输入框内容也自动变化。keyup.enteraddTodo这是事件监听。是v-on:的简写监听输入框的keyup.enter事件即按下回车键并触发addTodo方法。clickaddTodo监听按钮的点击事件。todoState.list.push(...)直接修改reactive对象内的数组Vue 能检测到变化并更新视图。newTodoText.value 修改ref的值必须通过.value属性。现在你可以在输入框打字点击“添加”或按回车数据会被添加到todoState.list中虽然还看不到但可以用浏览器 Vue Devtools 扩展查看。5.3 步骤三渲染待办列表与切换完成状态接下来我们要把todoState.list渲染成列表并可以切换每个事项的完成状态。这里会用到v-for列表渲染和v-model绑定复选框。!-- src/App.vue (更新 template 中的列表区) -- template div classapp header.../header main div classinput-section.../div !-- 2. 列表区 -- div classlist-section v-iftodoState.list.length 0 ul classtodo-list li v-fortodo in todoState.list :keytodo.id classtodo-item label :class{ completed: todo.completed } input typecheckbox v-modeltodo.completed classtodo-checkbox / span classtodo-text{{ todo.text }}/span /label button clickremoveTodo(todo.id) classremove-btn×/button /li /ul /div div v-else classempty-tip p 清单空空如也快添加你的第一个待办事项吧/p /div !-- 3. 状态区 (稍后填充) -- /main /div /template script setup // ... 之前的 script 代码保持不变 ... // 删除待办事项的方法 function removeTodo(id) { const index todoState.list.findIndex(todo todo.id id); if (index -1) { todoState.list.splice(index, 1); } } /script style /* 新增列表区样式 */ .list-section { margin-bottom: 2rem; } .todo-list { list-style: none; } .todo-item { display: flex; justify-content: space-between; align-items: center; padding: 18px 20px; margin-bottom: 12px; background-color: #f8f9fa; border-radius: 12px; border-left: 5px solid #3498db; transition: all 0.3s; } .todo-item:hover { background-color: #eef5ff; transform: translateY(-2px); } .todo-item label { display: flex; align-items: center; flex: 1; cursor: pointer; } .todo-checkbox { width: 20px; height: 20px; margin-right: 15px; cursor: pointer; } .todo-text { font-size: 1.1rem; color: #2c3e50; } .todo-text.completed { text-decoration: line-through; color: #95a5a6; opacity: 0.7; } .remove-btn { background: none; border: none; color: #e74c3c; font-size: 1.8rem; font-weight: bold; cursor: pointer; line-height: 1; padding: 0 8px; border-radius: 50%; transition: background-color 0.2s; } .remove-btn:hover { background-color: #ffebee; } .empty-tip { text-align: center; padding: 3rem 1rem; color: #7f8c8d; font-size: 1.2rem; } /style关键点解析v-iftodoState.list.length 0和v-else这是条件渲染。当列表有内容时显示列表否则显示提示文字。v-fortodo in todoState.list :keytodo.id列表渲染。遍历todoState.list数组为每个todo项生成一个li。:keyv-bind:key的简写是必须的它帮助 Vue 高效地更新和复用 DOM 元素。通常使用唯一标识符如id。v-modeltodo.completed将复选框的选中状态与todo.completed属性进行双向绑定。勾选或取消勾选会自动更新数据。:class{ completed: todo.completed }动态绑定 class。当todo.completed为true时会为元素添加completed这个 CSS 类从而实现文字的中划线效果。clickremoveTodo(todo.id)点击删除按钮时调用removeTodo方法并传入当前事项的id。todoState.list.splice(index, 1)使用数组的splice方法从响应式数组中移除一项Vue 能检测到并更新视图。现在你的应用已经可以添加、显示、勾选完成和删除待办事项了功能基本完整。5.4 步骤四添加状态统计与数据持久化为了让应用更实用我们添加两个功能1) 显示统计信息2) 刷新页面后数据不丢失本地存储。!-- src/App.vue (更新 template 中的状态区并补充 script) -- template div classapp header.../header main div classinput-section.../div div classlist-section v-iftodoState.list.length 0.../div div v-else classempty-tip.../div !-- 3. 状态区 -- div classstats-section v-iftodoState.list.length 0 div classstats span总计: strong{{ totalCount }}/strong 项/span span已完成: strong{{ completedCount }}/strong 项/span span未完成: strong{{ pendingCount }}/strong 项/span /div div classactions button clickclearCompleted classsecondary-btn清除已完成/button button clickclearAll classdanger-btn清空全部/button /div /div /main /div /template script setup import { ref, reactive, computed, onMounted, watch } from vue; // 引入新API const newTodoText ref(); const todoState reactive({ list: [] }); // 使用 computed 计算属性它们依赖响应式数据并缓存结果 const totalCount computed(() todoState.list.length); const completedCount computed(() todoState.list.filter(t t.completed).length); const pendingCount computed(() totalCount.value - completedCount.value); function addTodo() { /* ... 保持不变 ... */ } function removeTodo(id) { /* ... 保持不变 ... */ } // 清除所有已完成事项 function clearCompleted() { todoState.list todoState.list.filter(todo !todo.completed); } // 清空所有事项 function clearAll() { if (confirm(确定要清空所有待办事项吗)) { todoState.list []; } } // --- 数据持久化 (使用 localStorage) --- const STORAGE_KEY vue3-todo-app-data; // 1. 组件挂载时从 localStorage 读取数据 onMounted(() { const saved localStorage.getItem(STORAGE_KEY); if (saved) { try { todoState.list JSON.parse(saved); } catch (e) { console.error(读取本地存储数据失败:, e); } } }); // 2. 监听 todoState.list 的变化自动保存到 localStorage watch( () [...todoState.list], // 深度监听数组及其内部对象的变化 (newList) { localStorage.setItem(STORAGE_KEY, JSON.stringify(newList)); }, { deep: true } // 深度监听 ); /script style /* 新增状态区样式 */ .stats-section { padding-top: 1.5rem; border-top: 2px solid #f0f0f0; } .stats { display: flex; justify-content: space-around; margin-bottom: 1.5rem; font-size: 1rem; color: #555; } .stats strong { color: #2c3e50; font-size: 1.2rem; } .actions { display: flex; gap: 15px; justify-content: center; } .secondary-btn, .danger-btn { padding: 12px 25px; border: none; border-radius: 10px; font-size: 1rem; font-weight: bold; cursor: pointer; transition: all 0.3s; } .secondary-btn { background-color: #f1f2f6; color: #2c3e50; } .secondary-btn:hover { background-color: #dfe4ea; } .danger-btn { background-color: #ffeaa7; color: #d35400; } .danger-btn:hover { background-color: #fdcb6e; } /style关键点解析computed计算属性。用于派生状态。totalCount、completedCount、pendingCount都依赖于todoState.list。当列表变化时它们会自动重新计算并且在模板中像普通属性一样使用。这比在模板中写复杂逻辑更清晰、高效。onMounted生命周期钩子。在组件被挂载到 DOM 后执行。我们在这里从localStorage读取之前保存的数据。watch侦听器。用于监听响应式数据的变化并执行副作用。我们深度监听todoState.list任何变化增、删、改完成状态都会触发回调函数将最新数据保存到localStorage。todoState.list [...]直接给reactive对象的属性赋值也是响应式的会触发视图更新和watch侦听。至此一个功能完整、具备数据持久化的 Vue3 Todo 应用就完成了6. 运行结果与效果验证确保终端中npm run dev命令仍在运行。在浏览器中访问http://localhost:5173。你应该看到一个美观的待办事项应用界面。功能验证添加在输入框输入文字按回车或点击“添加”按钮新事项应出现在列表中。完成/取消点击事项前的复选框文字应出现/取消中划线底部“已完成”计数应相应变化。删除点击事项右侧的 “×” 按钮该事项应从列表中移除。统计底部应正确显示总计、已完成、未完成的数量。清除点击“清除已完成”按钮所有已完成事项应被移除。点击“清空全部”会弹出确认框确认后所有事项清空。持久化刷新浏览器页面之前添加的所有数据包括完成状态应该还在。如果一切正常恭喜你你已经成功构建了你的第一个 Vue3 应用。7. 常见问题与排查思路在按照步骤操作时你可能会遇到以下问题问题现象可能原因排查方式解决方案运行npm create vuelatest报错或很慢1. Node.js 版本过低。2. npm 源网络问题。3. 权限不足。1.node -v检查版本需 16。2. 尝试 pingregistry.npmjs.org。3. 在非系统目录创建项目。1. 升级 Node.js 到 LTS 版。2. 切换 npm 镜像源npm config set registry https://registry.npmmirror.com。3. 使用管理员权限或更换项目目录。npm run dev启动失败提示端口被占用5173 端口已被其他程序使用。查看终端错误信息。1. 关闭占用 5173 端口的程序。2. 修改 Vite 配置或使用其他端口启动npm run dev -- --port 3000。页面空白控制台有 Vue 警告或错误1. 组件导入路径错误。2. 模板语法错误。3.ref/reactive使用不当。1. 打开浏览器开发者工具 (F12)查看 Console 面板。2. 检查错误信息指向的文件和行号。1. 检查main.js中App.vue的导入路径。2. 仔细核对模板中的v-指令和变量名拼写。3. 确保在script setup中正确引入了所需的 API如ref,reactive。数据修改了但页面不更新1. 直接修改了非响应式对象。2. 对reactive对象进行了直接替换。1. 检查是否直接修改了ref的.value或reactive对象的属性。2. 使用 Vue Devtools 检查数据状态。1. 确保修改ref时使用了.value。2. 对于数组使用push,splice,filter等变更原数组的方法或使用新数组赋值。localStorage数据不生效1. 存储键STORAGE_KEY不一致。2. 数据格式不是合法 JSON。3. 浏览器隐私模式禁用localStorage。1. 检查getItem和setItem的 key 是否相同。2. 在 Application 面板查看 Storage。3. 检查JSON.parse是否报错。1. 确保读写使用相同的 key。2. 使用try...catch包裹JSON.parse。3. 确保浏览器支持并启用了localStorage。样式没有生效1. CSS 类名拼写错误。2.scoped样式影响了子组件。3. 样式被其他规则覆盖。1. 使用浏览器检查元素查看应用的 CSS 规则。2. 检查style标签是否有scoped。1. 核对类名和模板中的class绑定。2. 本文使用全局样式若用scoped需注意深度选择器。8. 最佳实践与工程建议通过这个简单项目我们可以提炼出一些适用于更大规模 Vue3 项目的工程实践状态结构设计对于稍复杂的状态像我们一样使用reactive包裹一个对象来集中管理比分散的多个ref更清晰。对于大型应用应考虑使用 PiniaVue 官方状态管理库。计算属性的使用像completedCount这样依赖其他状态派生出的值务必使用computed。它提供缓存避免不必要的重复计算且逻辑更集中。副作用分离数据持久化localStorage操作属于副作用。使用watch或专门的组合式函数Composables来管理保持主业务逻辑的纯净。例如可以将整个持久化逻辑抽离到一个useTodoPersistence函数中。组件拆分当App.vue变得庞大时应该拆分组件。例如可以将TodoInput、TodoList、TodoItem、TodoStats拆分成独立的.vue文件通过props传递数据通过emit触发事件。这能极大提高代码的可维护性和复用性。样式管理对于小型项目组件内style足够。对于大型项目考虑使用 CSS Modules、Scoped CSS 搭配预处理器如 Sass或 CSS-in-JS 方案如vue3-styled-components以解决样式冲突和复用问题。TypeScript 集成强烈建议在正式项目中使用 TypeScript。Vue3 对 TS 的支持是顶级的。它能提供更好的代码提示、类型安全和重构能力。在创建项目时直接选择 TypeScript 模板即可。代码规范尽早引入 ESLint 和 Prettier 来统一代码风格这能有效减少团队协作中的摩擦。create-vue创建项目时可以选择集成。生产环境构建开发完成后使用npm run build命令进行构建。Vite 会打包、压缩你的代码输出到dist目录。你可以将这个目录部署到任何静态网站托管服务如 GitHub Pages, Vercel, Netlify。9. 总结与后续学习方向在过去的“2小时”里我们完成了一次 Vue3 的高效入门。你不仅看到了一个 Todo 应用的诞生更重要的是你实践了 Vue3 最核心的几大概念响应式数据 (ref,reactive)、模板语法与指令 (v-model,v-for,v-if)、计算属性 (computed)、侦听器 (watch)以及生命周期钩子 (onMounted)。所有这些都通过script setup这个简洁的语法糖组织在一起。这个“极简版”项目就像一张地图帮你标出了 Vue3 核心区域的主要地标。接下来你可以沿着这些方向深入探索组件化深度实践尝试将本项目中的输入区、列表项、统计区拆分成独立的子组件学习props父传子、emit子传父和provide/inject跨层级传值。路由学习 Vue Router构建包含多个页面的单页应用 (SPA)。这是现代前端应用的标配。状态管理当组件间共享状态变得复杂时引入 Pinia。它比 Vuex 更简单、更符合 Composition API 的理念。组合式函数 (Composables)这是 Vue3 代码复用的利器。尝试将数据持久化、网络请求等逻辑封装成可复用的组合式函数。生态工具链了解 Vite 的更多配置、使用 Vue Devtools 进行调试、集成 UI 组件库如 Element Plus、Ant Design Vue、Vuetify 等。本文的完整项目源码你可以在你的本地vue3-todo-demo目录中找到。建议你在此基础上进行修改和扩展例如添加分类标签、设置优先级、设置提醒时间等这是巩固学习成果的最佳方式。Vue3 的学习曲线并没有想象中陡峭。抓住“响应式数据驱动视图”这个核心从一个小而美的项目开始实践你就能快速建立起信心并逐步解锁更强大的功能。
返回列表