青训营学习记录笔记
01 技术使用
todolist案例为前端案例中最为经典案例之一,几乎是前端学习一定会接触到的案例。目前已经有很多语言和框架来写的todolist案例。今天简单记录下使用vue建立todolist案例的学习过程。
本次TodoList待办案例编码使用到的技术有:
- vue2
- vue-cli
02 实现一个todoList静态页面
- 本次所创建的静态页面如下图:
- 先针对网页原型进行组件拆分,本次所拆分的组件可供参考:
- 分别对不同组件使用vue组件进行静态页面的实现:
-
App组件:
<template> <div id="root"> <div class="todo-container"> <div class="todo-wrap"> <TodoHeader/> <TodoList/> <TodoFooter/> </div> </div> </div> </template> <script> import TodoHeader from './components/TodoHeader.vue'; import TodoList from './components/TodoList.vue'; import TodoFooter from './components/TodoFooter.vue'; export default { name: 'App', components: { TodoHeader, TodoList, TodoFooter }, data() { return { todos:[ {id:'001',content:'学习',isDone:true}, {id:'002',content:'睡觉',isDone:true}, {id:'003',content:'玩原神',isDone:false}, ] } } </script> <style> body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-warning { color: #fff; background-color: rgb(255, 193, 7); border: 1px solid rgb(255, 180, 7); } .btn-warning:hover { color: #fff; background-color: rgb(255, 150, 7); } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #da7f58; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>样式使用的原生CSS来写
-
TodoHeader组件:
<template> <div class="todo-header"> <input type="text" placeholder="Please enter your todo name and press enter to confirm"/> </div> </template> <script> export default { name: 'TodoHeader', } </script> <style scoped> .todo-header input { width: 560px; height: 28px; font-size: 14px; border: 1px solid #ccc; border-radius: 4px; padding: 4px 7px; } .todo-header input:focus { outline: none; border-color: rgba(82, 168, 236, 0.8); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); } </style> -
TodoList组件:
<template> <ul class="todo-main"> <TodoItem v-for="todoObj in todos" :key="todoObj.id" /> </ul> </template> <script> import TodoItem from './TodoItem.vue'; export default { name: 'TodoList', components: { TodoItem }, } </script> <style scoped> .todo-main { margin-left: 0px; border: 1px solid #ddd; border-radius: 2px; padding: 0px; } .todo-empty { height: 40px; line-height: 40px; border: 1px solid #ddd; border-radius: 2px; padding-left: 5px; margin-top: 10px; } </style>在TodoList组件中,使用了v-for进行每个待办的遍历
-
TodoItem组件:
<template> <li> <label> <input type="checkbox" :checked="todo.isDone"/> <span>{{ todo.content }}</span> </label> <button class="btn btn-danger">删除</button> </li> </template> <script> export default { name: 'TodoItem', } </script> <style scoped> li { list-style: none; height: 36px; line-height: 36px; padding: 0 5px; border-bottom: 1px solid #ddd; } li label { float: left; cursor: pointer; } li label li input { vertical-align: middle; margin-right: 6px; position: relative; top: -1px; } li button { float: right; display: none; margin-top: 3px; } li:before { content: initial; } li:last-child { border-bottom: none; } li:hover { background-color: rgb(203, 234, 254); } li:hover button { display: block; } </style>在Item组件中,使用了checked="todo.isDone"进行复选框的初始设定
-
TodoFooter组件:
<template> <div class="todo-footer"> <label> <input type="checkbox"/> </label> <span> <span>已完成</span> / 全部 </span> <button class="btn btn-warning">清除已完成任务</button> </div> </template> <script> export default { name: 'TodoFooter', } </script> <style> .todo-footer { height: 40px; line-height: 40px; padding-left: 6px; margin-top: 5px; } .todo-footer label { display: inline-block; margin-right: 20px; cursor: pointer; } .todo-footer label input { position: relative; top: -1px; vertical-align: middle; margin-right: 5px; } .todo-footer button { float: right; margin-top: 5px; } </style>
03 实现TodoHeader组件功能
TodoHeader主要功能为一个复选框,首先要实现将用户的输入包装成一个todo对象,而对于在本地书写代码,没有后端服务器支撑的话,不能为每一个输入的id赋值,在此我们引用nanoid库来处理输入待办的ID
执行命令:npm install nanoid
为复选框添加键盘事件,本次所选择的是按下ente,r进行输入:@keyup.enter="add"
在vue的script部分添加一个名为add的methods:
<script> import {nanoid} from 'nanoid' export default { name: 'TodoHeader', methods: { add(){ if(!this.content.trim()) { this.content = '' return alert('输入内容不能为空!') } const todoObj = { id:nanoid(), content: this.content, isDone: false } this.addTodo(todoObj) //按enter后清空输入框的输入内容 this.content = '' } } } </script>
同时,考虑用户输入之后,再输入下一个待办的时候,希望的是复选框里内容为空:
在input框里输入v-model="content"
在methods里加入data:
data(){ return { content:'' } },
本案例未使用组件之间通信技术,对于增加一个todo的实现,是使用App组件的定义函数,再进行回调的方式:
App组件定义添加一个todo方法:
addTodo(todoObj){
this.todos.unshift(todoObj)
},
然后进行组件传参(props),后同:<TodoHeader :addTodo="addTodo"/>
在TodoHeader组件中接受:props:['addTodo']