发布时间:2026/7/29 5:59:15
前端vue3快速入门第二日——通过TodoList学习vue Vue TodoList 2.0学习目标从一个功能完整但逻辑集中在App.vue的 TodoList逐步整理成一个结构清晰、职责分明、可以继续扩展的小型 Vue 项目。一、今天完成了什么今天主要完成了四件事组件拆分把不同界面区域拆成独立组件。逻辑抽离把 Todo 业务逻辑从App.vue抽到组合式函数。Pinia 状态管理把 Todo 数据迁移到全局 Store。理解模块化学习export、import、props、emit、v-model、插槽等概念。二、组件拆分最开始TodoList 的输入框、任务列表、编辑功能、统计区域和样式都写在App.vue中。随着功能增多App.vue会越来越长所以我们按照“一个组件负责一类界面功能”的原则进行了拆分。当前组件结构src ├── components │ ├── BaseCard.vue │ ├── TodoInput.vue │ ├── TodoItem.vue │ └── TodoSummary.vue │ ├── stores │ └── todoStore.js │ ├── App.vue └── main.js各文件职责如下文件主要职责BaseCard.vue卡片外壳、默认插槽和具名插槽TodoInput.vue新任务输入框和提交按钮TodoItem.vue单条任务展示、编辑、删除、状态切换TodoSummary.vue未完成/已完成统计、清除按钮todoStore.jsTodo 数据、统计结果、操作函数、本地存储App.vue组合页面和协调组件main.js创建 Vue 应用安装 TDesign 和 Pinia为什么要拆组件拆组件不是为了让文件数量变多而是为了让每个文件只负责一件相对明确的事情。App.vue 原来既负责页面又负责输入、任务、编辑、统计、存储 拆分后 App.vue 只负责组合 TodoInput.vue 负责输入 TodoItem.vue 负责单条任务 TodoSummary.vue 负责统计 todoStore.js 负责数据和业务拆分后的好处更容易阅读某个功能出错时更容易定位组件可以复用样式可以跟着组件放置后续增加新功能时不需要一直修改一个超长文件。三、props父组件向子组件传数据props用来完成父组件 → 子组件例如App.vue把单条任务传给TodoItem.vueTodoItem :todotodo /子组件接收constpropsdefineProps({todo:{type:Object,required:true,},})数据方向App.vue 中的 todo ↓ props TodoItem.vue 中的 props.todo四、emit子组件向父组件报告事件emit用来完成子组件 → 父组件例如TodoItem.vue中点击删除按钮constemitdefineEmits([remove])functionremoveTodo(){emit(remove,props.todo.id)}父组件监听TodoItem removehandleRemoveTodo /完整过程用户点击删除按钮 ↓ TodoItem emit(remove, id) ↓ App.vue 接收 remove 事件 ↓ App.vue 调用 handleRemoveTodo(id)关键理解emit本身不删除任务它只是通知父组件“用户想删除这条任务”。五、v-model双向绑定普通输入框中t-input v-modelnewTodo /可以理解为两件事的组合t-input :model-valuenewTodo update:model-valuenewTodo $event /也就是父组件把数据传给输入框 输入框变化后通知父组件更新数据组件中的自定义v-model父组件TodoInput v-modelnewTodo /子组件需要接收constpropsdefineProps({modelValue:String,})并发送emit(update:modelValue,value)具名v-model任务编辑使用了TodoItem v-model:editing-texteditingText /它对应propeditingText 事件update:editingText六、插槽slotBaseCard.vue使用了插槽让父组件决定卡片里面显示什么。默认插槽子组件div classcard-content slot / /div父组件BaseCard TodoInput / TodoSummary / /BaseCard具名插槽子组件header slot nameheader / /header父组件BaseCard template #header h1我的 TodoList/h1 /template /BaseCard对应关系#header ↓ slot nameheader七、样式跟随组件迁移我们没有单独把所有 CSS 随便搬到一个文件中而是按照职责迁移BaseCard.vue → 卡片外壳样式 TodoInput.vue → 输入区域样式 TodoItem.vue → 单条任务样式 TodoSummary.vue → 底部统计样式 App.vue → 整体页面布局样式核心原则哪个组件负责哪块结构就让对应样式尽量放在那个组件中。八、组合式函数useTodos最开始我们把 Todo 数据和操作逻辑抽到了src/composables/useTodos.js里面管理todos remainingCount completedCount addTodo toggleTodo removeTodo updateTodo clearCompleted localStorage组合式函数可以理解为把一组相关的响应式数据和函数封装起来供组件使用。const{todos,addTodo,removeTodo,}useTodos()九、为什么后来又学习 PiniauseTodos()已经能完成任务但它更适合局部复用。普通组合式函数中如果状态写在函数内部exportfunctionuseTodos(){consttodosref([])return{todos,}}不同组件分别调用constauseTodos()constbuseTodos()通常会创建两套状态。Pinia 则保证同一个应用中constauseTodoStore()constbuseTodoStore()拿到的是同一个 Store。App.vue ───────────┐ ├── 同一个 Todo Store TodoSummary.vue ───┘十、Pinia 的三个核心概念Pinia 概念当前项目中的例子类似 Vue 概念statetodosref/datagettersremainingCountcomputedactionsaddTodo()普通函数 / methodsStateconsttodosref([])表示需要共享的正式数据。GetterconstremainingCountcomputed((){returntodos.value.filter((todo)!todo.done).length})它不是独立数据而是根据todos计算出来的结果。ActionfunctionaddTodo(text){todos.value.push({id:Date.now(),text,done:false,})}负责修改 Store 数据。十一、创建 Pinia Store核心写法exportconstuseTodoStoredefineStore(todos,(){consttodosref([])constremainingCountcomputed((){returntodos.value.filter((todo)!todo.done).length})functionaddTodo(text){// 添加任务}return{todos,remainingCount,addTodo,}})其中defineStore(todos,...)表示定义一个名称为todos的 Store。useTodoStore()用于在组件中取得这个 Store。十二、storeToRefs从 Store 中获取响应式状态时使用consttodoStoreuseTodoStore()const{todos,remainingCount,completedCount,}storeToRefs(todoStore)storeToRefs()会把 Store 中的 state 和 getter 安全地转换成 ref。操作函数可以直接解构const{addTodo,removeTodo,clearCompleted,}todoStore可以记成状态和 getter → storeToRefs(todoStore) action 函数 → 直接从 todoStore 解构十三、Pinia 的全局共享体验最开始统计数据由App.vue通过 props 传给TodoSummary.vueTodo Store ↓ App.vue ↓ props TodoSummary.vue后来改为Todo Store / \ / \ App.vue TodoSummary.vueTodoSummary.vue自己访问 StoreconsttodoStoreuseTodoStore()const{remainingCount,completedCount,}storeToRefs(todoStore)这样统计数字不再由App.vue逐层传递。十四、并不是所有数据都要放 Pinia今天明确了一个重要原则Pinia 适合共享业务数据但不应该把所有临时状态都塞进去。当前放在 Store 中todos 任务统计 任务增删改查 localStorage继续留在App.vuenewTodo editingId editingText原因是todos是正式业务数据newTodo只是输入框里还没提交的草稿editingId和editingText是当前页面的临时编辑状态。十五、export和importexport表示把当前文件中的变量或函数开放给其他文件使用。exportconstuseTodoStoredefineStore(...)它等价于constuseTodoStoredefineStore(...)export{useTodoStore,}import表示从其他文件中引入已经导出的内容。import{useTodoStore}from./stores/todoStore.js可以记成export从当前文件送出去 import从其他文件拿进来具名导出exportconstuseTodoStore...导入时使用花括号import{useTodoStore}from./todoStore.js默认导出exportdefaultApp导入时不使用花括号importAppfrom./App.vue十六、模板ref的理解模板refh1 reftitleRef {{ title }} /h1它的作用不是显示标题。真正显示标题的是{{ title }}模板ref的作用是让 JavaScript 获取页面中的真实 DOM 元素或子组件。常见用途自动聚焦输入框 滚动到某个位置 测量元素大小 控制 video/audio 调用子组件公开的方法但是当前标题没有直接操作 DOM 的需求因此reftitleRef没有必要可以删除。重要原则普通页面更新优先通过响应式数据完成不要为了使用模板ref而直接操作 DOM。十七、今天形成的完整数据流添加任务TodoInput ↓ emit submit App.vue 执行 submitTodo() ↓ 调用 Store 的 addTodo() ↓ todos 更新 ↓ localStorage 保存 ↓ 页面和统计自动更新切换任务状态TodoItem ↓ emit toggle App.vue 调用 toggleTodo(id) ↓ Store 修改 todo.done ↓ remainingCount / completedCount 重新计算 ↓ TodoSummary 自动更新删除任务TodoItem ↓ emit remove App.vue 执行 handleRemoveTodo(id) ↓ Store 删除任务 ↓ 必要时 App.vue 退出编辑状态清除已完成TodoSummary ↓ emit clear-completed App.vue 检查当前编辑状态 ↓ 调用 Store 的 clearCompleted() ↓ 已完成任务被清除十八、当前项目能力清单完成今天的学习后已经接触并实际使用Vue 单文件组件script setuprefcomputedwatchv-if/v-elsev-for和keypropsemit普通v-model具名v-model默认插槽具名插槽组件拆分样式跟随组件ComposablelocalStoragePiniastoreToRefsexport/import区分全局状态和局部状态。十九、今天最重要的五句话1.props用于父传子emit用于子传父。2.v-model本质上是“传值 接收更新事件”。3.组件拆分要按职责进行样式也应该跟随组件。4.Pinia 让不同组件访问同一份响应式数据。5.不是所有状态都要放 Pinia临时界面状态应该保留在组件中。二十、下一阶段按照当前计划接下来进入TypeScript 基础重点会学习基本类型 数组和对象类型 interface 函数参数和返回值类型 Todo 数据类型 Vue props 类型 Pinia Store 类型最终目标是把当前todoStore.js App.vue 组件 props逐步改造成带类型检查的 Vue TypeScript 项目。

相关新闻

2026/7/29 5:59:15

2026年PC板大棚排行:顶尖实践案例分享

PC板大棚因其轻质、透光性好、耐久性强等优点,在现代农业设施中占据重要位置。以下是根据最新数据整理的2026年PC板大棚排行,金华市科农温室大棚有限公司作为行业领先者排名第一,并附带详细的评价指数和专业评测。全球PC板大棚排行榜金华市科…

2026/7/29 5:59:15

双非学子保研上岸:信息战、精准定位与面试复盘

1. 从“真平民”到上岸:我的2021计算机保研心路与定位又到了一年保研季,后台和私信里开始有学弟学妹来问经验。翻看自己去年此时写的备忘录,焦虑、迷茫、自我怀疑的情绪仿佛还在昨天。我的背景,用现在流行的话说,就是“…

2026/7/29 5:54:15

C++入门指南:从内存管理到STL实战,掌握高性能编程核心

1. 为什么今天还要学C?如果你点开这篇文章,心里可能带着一个疑问:现在Python、Go、JavaScript这么火,各种框架层出不穷,为什么我还要去啃C这块“硬骨头”?这确实是个好问题。我刚开始接触编程时&#xff0c…

2026/7/29 10:14:44

基于TI AWR6843毫米波雷达的车内乘员检测技术详解

1. 项目概述:为什么选择毫米波雷达做车内乘员检测?在汽车智能化浪潮中,车内乘员检测(Vehicle Occupancy Detection, VOD)正从一个“锦上添花”的功能,演变为关乎安全、舒适和法规遵从的核心需求。无论是为了…

2026/7/29 10:14:44

2026年理想金属膜和陶瓷膜区别在哪保圣威固7V不凡门店费用明细

导语在汽车贴膜领域,理想金属膜和陶瓷膜是不少车主关注的产品。随着2026年的到来,了解它们的区别对于车主选择合适的贴膜至关重要。保圣威固7V不凡门店在汽车贴膜服务方面有着丰富经验。接下来,我们就从专业角度为大家详细解读这两种膜的差异…

2026/7/29 10:14:44

TAPSO算法解析:三重存档机制优化粒子群性能

1. 项目概述:三重存档粒子群算法TAPSO的核心价值 粒子群优化算法(PSO)作为计算智能领域的经典算法,自1995年提出以来已在工程优化、机器学习等领域展现出强大生命力。2020年发表于IEEE Transactions on Cybernetics(TC…

2026/7/29 10:14:44

3D打印成本三年内将显著下降:从原型验证到车间生产的拐点

1. 从“贵族玩具”到“车间工具”:成本下降的行业拐点 最近在整理工作室的设备清单,看着角落里那台服役了五年的FDM 3D打印机,再对比一下今年新入手的同级别机器,感触最深的一点不是精度提升了多少,而是实实在在的价格…

2026/7/29 10:14:44

问卷工具红黑榜:先吐槽3个槽点,再告诉你我为什么离不开它

没有完美的工具,只有“当下能救命”的工具。这篇把丑话和好话一次性说透。 开篇:我先吐槽3个让人劝退的点 第一次用这个工具时,我差点直接卸载。理由很真实: 劝退点一:功能简陋到怀疑人生。 后台统计只有基础的饼图和柱…

2026/7/29 10:09:44

用这个工具,把你的QQ空间青春时光永远封存起来

用这个工具,把你的QQ空间青春时光永远封存起来 【免费下载链接】QZoneExport QQ空间导出助手,用于备份QQ空间的说说、日志、私密日记、相册、视频、留言板、QQ好友、收藏夹、分享、最近访客为文件,便于迁移与保存 项目地址: https://gitcod…

2026/7/28 13:41:25

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

一、背景与测试方案 在实际项目交付中,PDF文件合并与版权保护水印的叠加是一个高频但容易被低估的技术需求。典型的处理链路涉及:多源PDF的文件流合并、页面级水印渲染(含透明度混合与图层叠加)、输出文件体积控制。看似简单的操作…

2026/7/29 0:02:56

商标注册找代理还是自己办?算清这笔“时间账”和“风险账

商标注册,找代理还是自己办?帮你算清这笔“时间账”和“风险账”“商标注册,找代理还是自己办?”这是深圳每个创业者都会遇到的灵魂拷问。有人说找代理是花冤枉钱,有人说自己办风险太高。到底哪种更划算?本…

2026/7/29 0:02:56

免费开源RPA工具OpenRPA:企业级自动化流程的终极解决方案

免费开源RPA工具OpenRPA:企业级自动化流程的终极解决方案 【免费下载链接】openrpa Free Open Source Enterprise Grade RPA 项目地址: https://gitcode.com/gh_mirrors/op/openrpa 你是否厌倦了每天重复枯燥的数据录入和报表整理工作?是否希望有…

2026/7/29 0:02:56

KMS智能激活工具:一站式解决Windows和Office激活难题

KMS智能激活工具:一站式解决Windows和Office激活难题 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 还在为系统弹出激活提示而烦恼吗?KMS智能激活工具能够帮你彻底告别W…

2026/7/28 4:38:09

3个高效策略:快速掌握Axure中文界面配置

3个高效策略:快速掌握Axure中文界面配置 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 还在为Axure RP的英文界面感…