【Vue】 实现TodoList案例(待办事项)

目录

组件化编码流程(通用)

1.实现静态组件:抽取组件,使用组件实现静态页面效果

2.展示动态数据:

1. 常规 HTML 属性

3.交互——从绑定事件监听开始

什么时候要用 event:

什么时候不需要用 event:

总结TodoList案例

总结不易!本章节对我有很大的收获, 希望对你也有帮助!!!


本节文件素材自取:https://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/vue-06/src

组件化编码流程(通用)

1.实现静态组件:抽取组件,使用组件实现静态页面效果

第一步,进行拆分组件!
首先定义好各个组件的名称,然后分别进行引入和注册
App组件
Item组件属于List的子组件,单独进行引入和注册
这里有当前模块化的html和css直接进行引入, 然后通过 自己拆分,来分别引入组件即可!
现在就定义好了一个静态的组件!

2.展示动态数据:

  • 数据的类型、名称是什么?
  • 数据保存在哪个组件?
在MyList中存在一堆待处理的事情的时候,我们肯定就是用数组对象来进行存储,每一个都具有当前标签的id号,内容title和是否完成done
进行渲染的时候,可以用我们之前学到的v-for = " todoObj in todos" 注意绑定:key=“todoObj.id”值
实际上是写成 v-for = "(title, index) in todos"

传入值给MyItem 进行值的接收~ 打印这里的生命周期钩子中todo对象

v-bind就是得到Vue里面的值 然后进行传给html标签里面的属性值使用!

1. 常规 HTML 属性

  • href: 链接的 URL

  • src: 图像、视频或其他资源的来源

  • alt: 图像的替代文本

  • title: 元素的提示信息

  • disabled: 控制按钮、输入框等元素的禁用状态

  • readonly: 使输入框成为只读

  • checked: 复选框或单选框的选中状态

  • value: 表单控件的值

  • placeholder: 表单控件的占位符文本

  • maxlength: 输入框允许的最大字符数

  • type: 表单控件的类型,如 textpasswordcheckbox

就好比 给img :src=“”图片传入地址

    3.交互——从绑定事件监听开始

    在MyHeader.vue中,进行事件添加, 每次按下回车,都会添加一条新的todo任务

    • @keyupv-on:keyup 的简写,它用于监听 keyup 事件。keyup 事件会在用户松开按键时触发。

    • .enter 是一个修饰符,它限制只在用户按下 Enter 键 时触发事件。也就是说,只有当用户按下 Enter 键并松开时,才会触发 add 方法。

    • add 是你在 Vue 组件中定义的方法,当这个事件触发时,Vue 会调用 add 方法。

    这里有两种办法来接受输入框的数据:

    1. 给这个add函数来进行添加

    • event 是触发 keyup 事件时,浏览器传递给事件处理函数的原生 DOM 事件对象。

    • event.target 是触发事件的元素(即 <input> 输入框)。

    • event.target.value 获取的是这个输入框的当前值,也就是用户输入的内容。

    什么时候要用 event

    1. 你需要获取触发事件的元素(比如按钮、输入框等): 比如你点击了一个按钮,想知道是哪个按钮触发了事件,或者想获取这个按钮的某个属性(比如按钮的文本、值等)。这时需要 event.target 来拿到这个元素。

    <button @click="handleClick">Click me</button>methods: {handleClick(event) {console.log(event.target); // 这里你就可以得到触发点击的那个按钮元素}
    }
    

    你需要获取更多的事件信息: 比如你按了某个键,想知道是哪个键被按下。你需要 event.key 来获取按下的键的名字(例如 "Enter""Escape" 等)。

    <input type="text" @keyup="handleKeyup">methods: {handleKeyup(event) {console.log(event.key); // 输出你按下的键名}
    }
    

    你需要阻止事件的默认行为: 比如你点击了一个提交按钮,但你不想让它立即提交表单,而是执行其他的操作。你可以使用 event.preventDefault() 来阻止表单的提交。

    <form @submit="handleSubmit"><button type="submit">Submit</button>
    </form>methods: {handleSubmit(event) {event.preventDefault(); // 阻止表单提交console.log("表单没有提交");}
    }
    

    你需要停止事件冒泡: 有时候你点击某个元素时,可能不希望事件传播到父元素(例如,你点击了按钮,但父元素的点击事件也不想被触发)。这时你可以使用 event.stopPropagation() 来停止事件的传播。

    <div @click="handleDivClick"><button @click="handleClick">Click me</button>
    </div>methods: {handleDivClick() {console.log("Div clicked");},handleClick(event) {event.stopPropagation(); // 阻止事件冒泡,不让父 div 的点击事件触发console.log("Button clicked");}
    }
    

    什么时候不需要event

    • 如果你不需要获取事件的具体信息(比如你只是希望某个方法被执行),就不需要用 event。比如你用 Vue 的 @click,然后直接调用一个方法,没有涉及到原生事件信息的处理时,就不需要传 event

    2. 采用v-modle进行双向数据绑定,来直接获取输入的title值

    v-model="title":实现了输入框的值与 title 数据的双向绑定。

    为了生成一个绝对不会重复的id号, 这里就推荐一个nanoid库进行生成唯一的id

    安装好nanoid库后,直接进行引入:然后打印出输入的对象看看效果!

    由于我们现在数据在MyHeader上 需要将数据传入到MyList内才能将数据进行渲染,但是我们现在实现不了兄弟组件之间的互传,就比如上面之前的List组件传至item组件, 它们之间的关系就是父子组件的关系, List引入了item组件,所以才可以通过props进行传输数据!

    这里我们只能先将header数据传入App 然后 才从App传入至List的方法可行!!!

    1. 先实现比较简单的这条线,将数据从App组件传向List就是用props即可,将todos数组放入App组件,进行传输:

    App组件:

    List获取App组件传来的todos 然后再传给item单个事件进行渲染:

    2.第二条线就是, 要将Header输入框的值传送给App组件!

    然后就只需要将receive名字换成addTodo 并且获得的todoObj进行unshift数组todos即可!

    Header组件进行数据检验!

    if(!event.target.value.trim()) return alert('输入不能为空')

    export default {name: 'MyHeader',props:['addTodo'],methods: {add(event) {// 检验数据if(!event.target.value.trim()) return alert('输入不能为空')// 将用户的输入包装成一个todo对象// console.log(event.target.value)const todoObj = {id:nanoid(), title: event.target.value, done:false}// console.log(todoObj)// 通知App组件添加一个todoObj对象this.addTodo(todoObj)event.target.value = ''}}
    }

    当我想要改变当前标签值的done时, 首先第一步就是要获得该事件的id号!再Item组件中~

    那么仍然再App组件内进行定义函数:来进行勾选或取消勾选当前事件,得到该id后 将当前事件的done进行反转!

    那么就要将该函数进行传递至item组件内, 就要进行连续传递两次

    item勾选or取消勾选的另一种方法!直接利用v-model的双向数据绑定, 来获取props传来的数组todo.done来控制当前的checkbox的勾选效果!

    但是这里有一个很明显的冲突:

    这里的todo.done 是props传进来的 是只读的 但是这里却被修改了

    1.      但是Vue的监测比较宽松,比如:let obj = {a: 1, b: 2}
    2.      obj.a = 666 这种只修改属性值, Vue是监测不到的
    3.      obj = {x: 100, y: 200} 这种修改整个对象 才是Vue能够监测到的

    所以强烈不建议这种写法,还是不要直接对props进行修改的好~

    定义删除item任务, 跟勾选是用养一个效果, 再App组件内进行创建deleteTodo函数 然后进行传递给item组件中!

    Footer计算任务:

    Footer组件要接收App传入的todos 然后来计算当前的全部任务和已完成任务数!

    <span>已完成{{ doneTotal }}</span> / 全部{{ todos.length }}
    export default {name:'MyFooter',props:['todos'],// 计算属性 因为我们要计算已完成的任务数computed: {// 简写 写成函数形式doneTotal() {// 写法不高级// let i = 0// this.todos.forEach(todo => {if(todo.done) i++})// return i// 第一个参数就是一个函数 第二个参数 用来做统计的初始值 就像是定义 i = 0// 数组的长度是几 这个函数就被调用几次// pre 就是上一次的值, current就是当前的值// 返回值就是下一次执行这个函数的pre来进行接收// 最后一次调用函数的返回值就是整个reduce方法的返回值// current就是每一个todo对象 就是数组里面的下标为pre当前内容// const x = this.todos.reduce((pre, current) => {//   return pre + (current.done ? 1 : 0)// }, 0)// return xreturn this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0)}}
    }
    

    计算已完成任务数,这里用到了reduce这个数组内置函数,用来进行筛选计算作用,那么就要放入计算函数内部进行返回!

    reduce() 方法对数组中的每个元素按序执行一个提供的 reducer 函数,每一次运行 reducer 会将先前元素的计算结果作为参数传入,最后将其结果汇总为单个返回值。

    全部勾选 or 全部不勾选按钮 以及 清除已经完成的任务

    Footer的input checkbox复选框:

    但是这里input 又采用:checkbox 进行获取isAll的值 还进行@click进行点击事件 所以二者可以进行合并为v-model= "isAll"

    正常流程是: get() → 用户修改 → set(value) → 响应式数据变了 → 自动触发 get() → 页面刷新

    清除已完成任务:

     本节文件素材自取:https://gitee.com/liu-yihao-hhh/i-love---vue/tree/master/vue-06/src

    总结TodoList案例

    1. 组件化编码流程:

      ​ (1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。

      ​ (2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:

      ​ 1).一个组件在用:放在组件自身即可。

      ​ 2). 一些组件在用:放在他们共同的父组件上(<span style="color:red">状态提升</span>)。

      ​ (3).实现交互:从绑定事件开始。

    2. props适用于:

      ​ (1).父组件 ==> 子组件 通信

      ​ (2).子组件 ==> 父组件 通信(要求父先给子一个函数)

    1. 使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!

    2. props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。

    总结不易!本章节对我有很大的收获, 希望对你也有帮助!!!

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904295.shtml

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    【Bootstrap V4系列】学习入门教程之 组件-卡片(Card)

    Bootstrap V4系列 学习入门教程之 组件-卡片&#xff08;Card&#xff09; 卡片&#xff08;Card&#xff09;一、Example二、Content types 内容类型2.1 Body 主体2.2 Titles, text, and links 标题、文本和链接2.3 Images 图片2.4 List groups 列表组2.5 Kitchen sink 洗涤槽…

    java学习之数据结构:四、树(代码补充)

    这部分主要是用代码实现有序二叉树、树遍历、删除节点 目录 1.构建有序二叉树 1.1原理 1.2插入实现 2.广度优先遍历--队列实现 3.深度优先遍历--递归实现 3.1先序遍历 3.2中序遍历 3.3后序遍历 4.删除 4.1删除叶子节点 4.2删除有一棵子树的节点 4.3删除有两棵子树的节…

    架构进阶:什么是数据架构,如何理解数据架构?(华为)

    数据架构是企业架构的重要组成部分,DAMA、IBM 及国内大厂对其定义各有侧重。它包含数据资产目录、数据标准、数据模型和数据分布四个组件。数据资产目录可梳理企业数据资产,数据标准统一数据含义和规则,数据模型反映业务对象关联关系,数据分布呈现数据流动情况。数据架构是…

    Unity SpriteEditor(精灵图片编辑器)

    &#x1f3c6; 个人愚见&#xff0c;没事写写笔记 &#x1f3c6;《博客内容》&#xff1a;Unity3D开发内容 &#x1f3c6;&#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f50e;SpriteEditor&#xff1a; 精灵图片编辑器 &#x1f4cc;用于编辑2D游戏开发中使用的Sp…

    【网络原理】从零开始深入理解HTTP的报文格式(一)

    本篇博客给大家带来的是网络HTTP协议的知识点, 重点介绍HTTP的报文格式. &#x1f40e;文章专栏: JavaEE初阶 &#x1f680;若有问题 评论区见 ❤ 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 . 王子,公主请阅&#x1f68…

    ElasticSearch深入解析(九):Object、Nested、Flattened类型

    文章目录 一、Object 类型&#xff1a;默认的嵌套对象处理方式核心原理典型场景关键限制 二、Nested 类型&#xff1a;解决嵌套数组的关联查询核心原理典型场景使用示例注意事项 三、Join 类型&#xff1a;跨文档的父子关联核心原理典型场景使用示例注意事项 四、Flattened 类型…

    36、C#中的⽅法声明参数关键字params,ref,out的意义及⽤法

    在C#中&#xff0c;params、ref 和 out 是方法声明中用于修饰参数的关键字&#xff0c;它们各自有不同的用途和语义。以下是它们的详细说明和用法&#xff1a; 1、 params 关键字 意义 params 允许方法接受可变数量的参数&#xff0c;这些参数会被编译为一个数组。适用于参数…

    【大模型实战篇】华为信创环境采用vllm部署QwQ-32B模型

    1. 背景 本文分享在华为昇腾机器上部署QwQ-32B模型的实践。 首先华为自己是提供了一套在信创机器&#xff08;NPU&#xff09;上部署模型的方案【1】&#xff0c;但是部署之后&#xff0c;测试发现会有输出截断的现象。QwQ-32B本身是支持128k的最大上下文长度&#xff0c;定位…

    前端面经-VUE3篇(二)--vue3基础知识(二)计算属性(computed)、监听属性(Watch)

    一、计算属性(computed) 计算属性&#xff08;Computed Properties&#xff09;是 Vue 中一种特殊的响应式数据&#xff0c;它能基于已有的响应式数据动态计算出新的数据。 计算属性有以下特性&#xff1a; 自动缓存&#xff1a;只有当它依赖的响应式数据发生变化时&#xff…

    [预备知识] 5. 优化理论(一)

    优化理论 梯度下降&#xff08;Gradient Descent&#xff09; 数学原理与可视化 梯度下降是优化领域的基石算法&#xff0c;其核心思想是沿负梯度方向迭代更新参数。数学表达式为&#xff1a; θ t 1 θ t − α ∇ θ J ( θ t ) \theta_{t1} \theta_t - \alpha \nabla…

    大模型微调Fine-tuning:从概念到实践的全面解析

    目录 引言 一、什么是大模型微调&#xff1f; 1.1 预训练与微调的区别 1.2 微调的技术演进 二、为什么需要微调&#xff1f; 2.1 解决大模型的固有局限 2.2 微调的优势 三、主流微调方法 3.1 全参数微调 3.2 参数高效微调&#xff08;PEFT&#xff09; 四、微调实践指…

    Docker 使用下 (二)

    Docker 使用下 &#xff08;二&#xff09; 文章目录 Docker 使用下 &#xff08;二&#xff09;前言一、初识Docker1.1 、Docker概述1.2 、Docker的历史1.3 、Docker解决了什么问题1.4 、Docker 的优点1.5 、Docker的架构图 二、镜像三、容器四、数据卷4.1、数据卷的概念4.2 、…

    洛谷P12238 [蓝桥杯 2023 国 Java A] 单词分类

    [Problem Discription] \color{blue}{\texttt{[Problem Discription]}} [Problem Discription] Copy from luogu. [Analysis] \color{blue}{\texttt{[Analysis]}} [Analysis] 既然都是字符串前缀的问题了&#xff0c;那当然首先就应该想到 Trie \text{Trie} Trie 树。 我们可…

    pta作业中有启发性的程序题

    1 【知识点】&#xff1a;多态 函数接口定义&#xff1a; 以Student为基类&#xff0c;构建GroupA, GroupB和GroupC三个类 裁判测试程序样例&#xff1a; #include<iostream> #include <string> using namespace std;/* 请在这里填写答案 */int main() {const …

    Scrapy框架之CrawlSpider爬虫 实战 详解

    CrawlSpider 是 Scrapy 框架中一个非常实用的爬虫基类&#xff0c;它继承自 Spider 类&#xff0c;主要用于实现基于规则的网页爬取。相较于普通的 Spider 类&#xff0c;CrawlSpider 可以根据预定义的规则自动跟进页面中的链接&#xff0c;从而实现更高效、更灵活的爬取。 Scr…

    Glide 如何加载远程 Base64 图片

    最近有个需求&#xff0c;后端给出的图片地址并不是正常的 URL&#xff0c;而且需要一个接口去请求&#xff0c;但是返回的是 base64 数据流。这里不关心为啥要这么多&#xff0c;原因有很多&#xff0c;可能是系统的问题&#xff0c;也可能是能力问题。当然作为我们 Android 程…

    004-nlohmann/json 快速认识-C++开源库108杰

    了解 nlohmann/json 的特点&#xff1b;理解编程中 “数据战场”划分的概念&#xff1b;迅速上手多种方式构建一个JSON对象&#xff1b; 1 特点与安装 nlohmann/json 是一个在 github 长期霸占 “JSON” 热搜版第1的CJSON处理库。它的最大优点是与 C 标准库的容器数据&#xf…

    #基础Machine Learning 算法(上)

    机器学习算法的分类 机器学习算法大致可以分为三类&#xff1a; 监督学习算法 (Supervised Algorithms&#xff09;:在监督学习训练过程中&#xff0c;可以由训练数据集学到或建立一个模式&#xff08;函数 / learning model&#xff09;&#xff0c;并依此模式推测新的实例。…

    正弦波、方波、三角波和锯齿波信号发生器——Multisim电路仿真

    目录 Multisim使用教程说明链接 一、正弦波信号发生电路 1.1正弦波发生电路 电路组成 工作原理 振荡频率 1.2 正弦波发生电路仿真分析 工程文件链接 二、方波信号发生电路 2.1 方波发生电路可调频率 工作原理 详细过程 2.2 方波发生电路可调频率/可调占空比 调节占空比 方波产生…

    【AND-OR-~OR锁存器设计】2022-8-31

    缘由锁存器11111111111-硬件开发-CSDN问答 重置1&#xff0c;不论输入什么&#xff0c;输出都为0&#xff1b; 重置0&#xff0c;输入1就锁住1 此时输入再次变为0&#xff0c;输出不变&#xff0c;为锁住。