Vue3实战入门:手把手拆解Todo应用

46 阅读6分钟

Vue3实战入门:手把手拆解Todo应用

前情提要:每个Vue学习者都踩过的坑

你是否经历过这样的困境?看文档时觉得v-model、v-for这些指令都懂,打开编辑器却不知从何下手;明明理解了响应式原理,真写代码时数据更新总是不按预期。这个Todo项目就像一面照妖镜,能照出Vue学习路上的认知盲区。

一、Vue3核心指令速览

指令描述
v-bind用于将 Vue 实例的数据绑定到 HTML 元素的属性上。
v-if用于根据表达式的值来条件性地渲染元素或组件。
v-for用于根据数组或对象的属性值来循环渲染元素或组件。
v-on用于在 HTML 元素上绑定事件监听器,使其能够触发 Vue 实例中的方法或函数。
v-model用于在表单控件和 Vue 实例的数据之间创建双向数据绑定。

二、项目实战应用

直接切入正题,讲讲 Vue 在这个 Todos 应用里到底有多厉害。


First: 建立框架

<script src="./vue.js"></script>
 <div id="app">
      
   </div>
       <script type="module">
        const {
            createApp,// 创建Vue3应用
            ref // 响应式数据
         } = Vue;

        const app = createApp({
            setup(){
               
            }
         })
         app.mount("#app");
    </script>    

这段代码是在创建一个最基本的Vue 3应用框架。就像盖房子要先搭架子一样,这里就是在搭Vue应用的架子。

  1. 首先用<script>标签引入了Vue.js文件,就像我们要用工具得先把工具箱拿来一样。这里的./vue.js表示Vue库文件放在当前目录下。

  2. 然后有个<div id="app">的空容器,这就像在页面上划出一块地,专门给Vue应用使用,之后Vue渲染的内容都会放在这个div里面。

  3. 接着看到两个相似的代码块都在从Vue对象中解构出createAppref

    • createApp是用来创建Vue应用的"施工队"
    • ref是用来创建响应式数据的"魔法工具"(虽然这里还没用上)
  4. 最后用createApp创建了一个Vue应用实例,并调用mount("#app")把这个应用挂载到之前准备好的那个div容器上。不过现在这个应用还是个空壳子,因为setup函数里什么都没写。

这就像你要装修房子:

  • 先找来装修工具(引入Vue.js)
  • 划定装修区域(准备#app容器)
  • 挑选需要的工具(解构createApp和ref)
  • 开始装修施工(createApp和mount)
  • 不过现在还没决定具体怎么装修(setup为空)

Sconed: 打造房子

image.png

1. 标题和输入表单
<h1>ToDo-It</h1>
<form @submit.prevent="addTodo">
    <input 
        type="text" 
        v-model="title" 
        placeholder="请输入任务" 
        required
    >
    <button type="submit">添加任务</button>
</form>

<form> :表单用于提交新任务。 @submit.prevent="addTodo":当用户提交表单时,阻止默认刷新行为,并调用 addTodo 方法。

<input> :文本输入框,绑定到 title 变量(v-model="title"),用户在这里输入任务内容 placeholder:提示用户输入。 required:确保输入不能为空。

<button> :提交按钮,点击后触发 addTodo


2. 显示当前输入的任务
<p v-if="title == ''">添加的任务: <strong>暂无</strong></p>
<p v-else>添加的任务:{{ title }}</p>

v-if="title == ''" :如果 title 为空(用户还没输入),显示  "暂无"v-else:如果用户输入了内容,显示当前输入的任务({{ title }}是上述v-model="title"文本框的内容)。


3. 任务列表展示
<template v-if="todoList.length === 0">
    {{ Loading }}
</template>
<template v-else>
    <ul>
        <li v-for="(todo, index) in todoList" :key="index">
            {{ todo }}
            <button @click="removeTodo(index)">删除</button>
        </li>
    </ul>
</template>

v-if="todoList.length === 0" : 如果 todoList 是空的(还没有任务),显示 {{Loading}}

v-else:如果 todoList 有任务,渲染一个 <ul> 列表。 v-for="(todo, index) in todoList" :遍历 todoList,显示每个任务 todo 和对应的索引 index:key="index" :Vue 要求列表渲染时必须提供唯一的 key,这里用 index 作为标识。 <button @click="removeTodo(index)">删除</button> : 每个任务旁边有个  "删除"  按钮,点击时调用 removeTodo(index),传入当前任务的索引,以便删除它。


重点:

{{ Loading }}  、todoList {{title}} 、addTodo 和 removeTodo 方法,这些需要在 Vue 的 setup() 里实现(用 ref 动态渲染)。

这个模板已经搭建好了 UI 结构,接下来只需要在 Vue 的 setup() 里补充数据和方法,就能让整个应用跑起来! 🚀

Third:装修房子

image.png

1. 定义响应式数据(ref
const todoList = ref([]);       // 存储所有待办事项(初始为空数组)
const Loading = "Nothing to do!"; // 列表为空时的提示文字
const title = ref("");          // 绑定输入框的内容(初始为空)

todoList:用 ref([]) 创建一个响应式数组,用来存储所有的任务(比如 ["买菜", "写作业"])。

Loading:只是一个普通字符串,当任务列表为空时显示(对应模板里的 {{ Loading }})。

title:用 ref("") 创建一个响应式字符串,绑定到输入框(v-model="title"),实时存储用户输入的任务内容。


2. 添加任务(addTodo 函数)
const addTodo = () => {
    todoList.value.push(title.value); // 把当前输入的任务添加到列表
    title.value = "";                 // 清空输入框
};

当用户 提交表单<form @submit.prevent="addTodo">)时触发:

todoList.value.push(title.value) :把输入的内容(title.value)添加到 todoList 数组。 title.value = "" :清空输入框(因为 v-model 是双向绑定的,界面也会自动更新)。


3. 删除任务(removeTodo 函数)
const removeTodo = (index) => {
    todoList.value.splice(index, 1); // 根据索引删除对应任务
};

当用户点击  "删除" 按钮@click="removeTodo(index)")时触发:

splice(index, 1) :从 todoList 数组中删除指定 index 的任务(比如点击第 2 个任务的删除按钮,index 就是 1)。


4. 返回数据和方法(return
return {
    todoList,  // 让模板能访问任务列表
    Loading,   // 让模板能显示加载提示
    title,     // 让模板能绑定输入框
    addTodo,   // 让表单能调用添加方法
    removeTodo // 让按钮能调用删除方法
};
  • setup() 必须返回所有模板需要的东西,否则模板里用不了。
  • 这样模板里的 v-for="todo in todoList"@click="removeTodo(index)" 等才能正常工作。

整体流程(用户视角)

  1. 输入任务:在输入框打字,title 自动更新。
  2. 添加任务:按回车或点按钮,触发 addTodo,任务被添加到列表,输入框清空。
  3. 删除任务:点击某个任务旁边的 "删除" 按钮,触发 removeTodo,该任务从列表中消失。

你可能想问的问题

  • 为什么用 ref
    因为 Vue 3 需要用 ref 或 reactive 让数据变成 响应式(数据变,界面自动更新)。
  • 为什么 todoList.value.push 要用 .value
    因为 ref 创建的变量是一个包装对象,真实数据存在 .value 里(但在模板里不用写 .value,Vue 会自动解包)。
  • splice(index, 1) 是什么意思?
    这是 JavaScript 的数组方法,index 表示要删除的位置,1 表示删除 1 个元素。

总结

这段代码让之前的 HTML 模板 "活" 起来了!现在这个待办事项应用可以:
✅ 添加任务
✅ 显示任务列表
✅ 删除任务
✅ 自动更新界面