一、🧑💻todo案例
🔥1.0_todo案例-创建工程和组件
目标: 新建工程, 准备好所需的一切
- 需求1: 创建新工程
- 需求2: 分组件创建 – 准备标签和样式
分析:
①:初始化todo工程
②:创建3个组件和里面代码(在预习资料.md复制)
③:把styles的样式文件准备好(从预习资料复制)
④: App.vue引入注册使用, 最外层容器类名todoapp
预先准备: 把styles的样式文件准备好 在App.vue引入使用(文件样式在最底下)
// 1.0 样式引入 import "./styles/base.css" import "./styles/index.css"
根据需求: 我们定义3个组件准备复用
components/TodoHeader.vue - 复制标签和类名
<template> <header class="header"> <h1>todos</h1> <input id="toggle-all" class="toggle-all" type="checkbox" > <label for="toggle-all"></label> <input class="new-todo" placeholder="输入任务名称-回车确认" autofocus /> </header> </template> <script> export default { } </script>
components/TodoMain.vue - 复制标签和类名
<template> <ul class="todo-list"> <!-- completed: 完成的类名 --> <li class="completed" > <div class="view"> <input class="toggle" type="checkbox" /> <label>任务名</label> <button class="destroy"></button> </div> </li> </ul> </template> <script> export default { } </script>
components/TodoFooter.vue - 复制标签和类名
<template> <footer class="footer"> <span class="todo-count">剩余<strong>数量值</strong></span> <ul class="filters"> <li> <a class="selected" href="javascript:;" >全部</a> </li> <li> <a href="javascript:;">未完成</a> </li> <li> <a href="javascript:;" >已完成</a> </li> </ul> <button class="clear-completed" >清除已完成</button> </footer> </template> <script> export default { } </script>
App.vue中引入和使用
<template> <section class="todoapp"> <!-- 除了驼峰, 还可以使用-转换链接 --> <TodoHeader></TodoHeader> <TodoMain></TodoMain> <TodoFooter></TodoFooter> </section> </template> <script> // 1.0 样式引入 import "./styles/base.css" import "./styles/index.css" import TodoHeader from "./components/TodoHeader"; import TodoMain from "./components/TodoMain"; import TodoFooter from "./components/TodoFooter"; export default { components: { TodoHeader, TodoMain, TodoFooter, }, }; </script>
🔥1.1_todo案例-铺设待办任务
目的: 把待办任务, 展示到页面TodoMain.vue组件上
- 需求1: 把待办任务, 展示到页面TodoMain.vue组件上
- 需求2: 关联选中状态, 设置相关样式
分析:
①: App.vue – 准备数组传入TodoMain.vue内
②: v-for循环展示数据
③: v-model绑定复选框选中状态
④: 根据选中状态, 设置完成划线样式
App.vue
<TodoMain :arr="showArr"></TodoMain> export default { data() { return { list: [ { id: 100, name: "吃饭", isDone: true }, { id: 201, name: "睡觉", isDone: false }, { id: 103, name: "打豆豆", isDone: true }, ], }; } };
TodoMain.vue
<template> <ul class="todo-list"> <!-- 2.2 循环任务-关联选中状态-铺设数据 --> <!-- completed: 完成的类名 --> <li :class="{completed: obj.isDone}" v-for="(obj, index) in arr" :key='obj.id'> <div class="view"> <input class="toggle" type="checkbox" v-model="obj.isDone"/> <label>{{ obj.name }}</label> <!-- 4.0 注册点击事件 --> <button @click="delFn(index)" class="destroy"></button> </div> </li> </ul> </template> <script> export default { props: ["list"] }; </script> <style> </style>
🔥1.2_todo案例-添加任务
目标: 在顶部输入框输入要完成的任务名, 敲击回车, 完成新增功能
- 需求: 输入任务敲击回车, 新增待办任务
分析:
①: TodoHeader.vue – 输入框 – 键盘事件 – 回车按键
②: 子传父, 把待办任务 – App.vue中 – 加入数组list里
③: 原数组改变, 所有用到的地方都会更新
④: 输入框为空, 提示用户必须输入内容
TodoHeader.vue
<template> <header class="header"> <h1>todos</h1> <input id="toggle-all" class="toggle-all" type="checkbox" v-model="isAll"> <label for="toggle-all"></label> <!-- 3.0 键盘事件-回车按键 3.1 输入框 - v-model获取值 --> <input class="new-todo" placeholder="输入任务名称-回车确认" autofocus @keydown.enter="downFn" v-model="task" /> </header> </template> <script> // 3. 目标 - 新增任务 export default { data(){ return { task: "" } }, methods: { downFn(){ if (this.task.trim().length === 0) { alert("任务名不能为空"); return; } // 3.2(重要) - 当前任务名字要加到list数组里 // 子传父技术 this.$emit("create", this.task) this.task = "" } } } </script>
App.vue
<TodoHeader @create="createFn"></TodoHeader> methods: { createFn(taskName){ // 添加任务 // 3.3 push到数组里 let id = this.list.length == 0 ? 100 : this.list[this.list.length - 1].id + 1 this.list.push({ id: id, name: taskName, isDone: false }) }, }
🔥1.3_todo案例-删除任务
目标: 实现点x, 删除任务功能
- 需求: 点击任务后的x, 删除当前这条任务
分析:
①: x标签 – 点击事件 – 传入id区分
②: 子传父, 把id传回– App.vue中 – 删除数组list里某个对应的对象
③: 原数组改变, 所有用到的地方都会更新
App.vue - 传入自定义事件等待接收要被删除的序号
<TodoMain :arr="showArr" @del="deleteFn"></TodoMain> methods: { deleteFn(theId){ // 删除任务 let index = this.list.findIndex(obj => obj.id === theId) this.list.splice(index, 1) }, },
TodoMain.vue - 把id传回去实现删除(想好数据在哪里, 就在哪里删除)
<!-- 4.0 注册点击事件 --> <button class="destroy" @click="delFn(obj.id)"></button> methods: { delFn(id){ // 4.1 子传父 this.$emit('del', id) } }