
时间管理永远都是提升工作和学习效率的必备法门,你在平时的工作学习中是否也有做计划和管理计划的习惯呢? 本题需要在已提供的基础项目中使用 Vue.js 知识实现一个简易的任务管理器。
在开始答题前,你需要在线上环境终端中键入以下命令,下载并解压所提供的文件。
wget https://labfile.oss.aliyuncs.com/courses/7835/exam13-imi.zip && unzip exam13-imi.zip && rm exam13-imi.zip下载完成之后的目录结构如下:
├── css
│ └── style.css # 页面样式文件
├── img
│ └── icon.png # 页面所需小图标
├── index.html # 页面布局即逻辑编码文件
└── js
└── vue.js # 版本为 2.x 的 Vue.js 框架源码下载后,选中 index.html 右键启动 Web Server 服务(Open with Live Server),让项目运行起来。
接着,打开环境右侧的【Web 服务】,就可以在浏览器中看到如下效果:

当前显示仅有静态布局,并未实现具体功能。
请在
index.html文件中使用默认提供的 DOM 结构(即基础项目提供的 DOM 结构和指定 id 不能改变),使用 Vue 2.x 语法实现任务管理器功能。 具体需求如下: 1. 页面加载后默认显示 “暂无数据”。 最终实现效果如下:

2. 在输入框中输入内容并点击 “确认” 按钮后,将输入内容添加到任务列表。 最终实现效果如下:

3. 新增任务添加在已有任务后面。 最终实现效果如下:

4. 点击每条任务右侧的“删除”图标该任务会从任务列表中移除。 最终实现效果如下:


5. 底部 “总数” 右侧显示当前任务列表中的数量。 最终实现效果如下:

6. 点击底部的 “清除” 将清空任务列表中的数据,任务列表处恢复 “暂无数据” 的默认显示。 最终实现效果如下:


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>任务管理器</title>
<link type="text/css" href="css/style.css" rel="stylesheet" />
</head>
<body>
<div id="box">
<div class="head">
<h2>Todos</h2>
<p>罗列日常计划,做一个时间管理大师!</p>
<div class="input">
<span>内容</span>
<input type="text" placeholder="请输入你要做的事" v-model="newTodo"/>
<span id='add' @click="addTodo">确认</span>
</div>
</div>
<ul class="list">
<li v-if="todos.length === 0">
暂无数据
</li>
<li v-else v-for="(todo, index) in todos" :key="index">
<!-- 前面的序号 -->
<span class="xh">{
{ index + 1 }}</span>
<!-- 列表内容 -->
<span>{
{ todo }}</span>
<!-- 删除按钮 -->
<span class="qc" @click="removeTodo(index)"></span>
</li>
<li v-if="todos.length > 0">
<b>
总数:{
{ todos.length }}
</b>
<b id='clear' @click="clearTodos">清除</b>
</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
var top = new Vue({
el:"#box",
data: {
todos: ['学习', '吃饭', '睡觉'],
newTodo: ''
},
methods: {
addTodo() {
if (this.newTodo.trim()!== '') {
this.todos.push(this.newTodo);
this.newTodo = '';
}
},
removeTodo(index) {
this.todos.splice(index, 1);
},
clearTodos() {
this.todos = [];
}
}
});
</script>
</body>
</html><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>任务管理器</title>
<link type="text/css" href="css/style.css" rel="stylesheet" />
</head>
<body>
<div id="box">
<div class="head">
<h2>Todos</h2>
<p>罗列日常计划,做一个时间管理大师!</p>
<div class="input">
<span>内容</span>
<input type="text" placeholder="请输入你要做的事" v-model="newTodo"/>
<span id='add' @click="addTodo">确认</span>
</div>
</div>
<ul class="list">
<li v-if="todos.length === 0">
暂无数据
</li>
<li v-else v-for="(todo, index) in todos" :key="index">
<!-- 前面的序号 -->
<span class="xh">{
{ index + 1 }}</span>
<!-- 列表内容 -->
<span>{
{ todo }}</span>
<!-- 删除按钮 -->
<span class="qc" @click="removeTodo(index)"></span>
</li>
<li v-if="todos.length > 0">
<b>
总数:{
{ todos.length }}
</b>
<b id='clear' @click="clearTodos">清除</b>
</li>
</ul>
</div>
<script src="js/vue.js"></script>
<script>
var top = new Vue({
el: "#box",
data: {
todos: ['学习', '吃饭', '睡觉'],
newTodo: ''
},
methods: {
addTodo() {
if (this.newTodo.trim()!== '') {
this.todos.push(this.newTodo);
this.newTodo = '';
}
},
removeTodo(index) {
this.todos.splice(index, 1);
},
clearTodos() {
this.todos = [];
}
}
});
</script>
</body>
</html><head> 部分,设置了页面的字符编码为 utf-8,并引入了一个外部的 CSS 文件 css/style.css 来进行样式设置。<body> 部分,有一个 id 为 box 的 div 容器,里面包含了任务管理器的主要内容。div 容器内的 head 部分,有一个 h2 标题和一段提示信息,还有一个 div 作为输入框区域。span 元素作为输入提示,一个 input 元素,其使用了 Vue 的 v-model 指令绑定了 newTodo 数据,用户输入的内容会实时存储在 newTodo 中。还有一个 span 元素作为确认按钮,绑定了 @click 事件,点击时调用 addTodo 方法。ul 元素作为任务列表容器,class 为 list。todos 数组长度为 0 时,使用 v-if 指令显示 li 元素中的 “暂无数据”。todos 数组长度不为 0 时,使用 v-else 和 v-for 指令遍历 todos 数组,对于每个元素,显示一个带有序号(通过 index + 1)、任务内容(通过 { { todo }} 插值表达式)和删除按钮(绑定 @click 事件调用 removeTodo 方法)的 li 元素。li 元素在 todos 长度大于 0 时显示,显示任务总数和一个清除按钮(绑定 @click 事件调用 clearTodos 方法)。var top = new Vue({
el: "#box",
data: {
todos: ['学习', '吃饭', '睡觉'],
newTodo: ''
},
methods: {
addTodo() {
if (this.newTodo.trim()!== '') {
this.todos.push(this.newTodo);
this.newTodo = '';
}
},
removeTodo(index) {
this.todos.splice(index, 1);
},
clearTodos() {
this.todos = [];
}
}
});el 选项指定该 Vue 实例管理的元素为 id 为 box 的元素。data 选项定义了两个数据属性: todos 是一个数组,初始值包含 ['学习', '吃饭', '睡觉'],存储任务列表。newTodo 是一个空字符串,存储用户在输入框输入的新任务。addTodo() 方法: trim() 方法去除 newTodo 的前后空格,如果不为空,则将 newTodo 的内容添加到 todos 数组中,并将 newTodo 重置为空字符串,以便用户输入下一个任务。removeTodo(index) 方法: index 参数,使用 splice() 方法从 todos 数组中删除指定索引的元素。clearTodos() 方法: todos 数组清空。#box {
padding: 0 20px;
}
#box.list li span{
float: left;
height: 20px;
line-height: 20px;
margin: 10px 0;
text-align: center;
}
#box.list li span:first-child{
width: 50px;
border-right: 1px solid #ccc;
margin-right: 10px;
}
#box.list li span:last-child{
width: 30px;
background: url(../img/icon.png) no-repeat center center;
background-size: 50%;
float: right;
margin-right: 20px;
cursor: pointer;
}
#box.list li:last-child b:first-child{
float: left;
}
#box.list li:last-child b:last-child{
float: right;
cursor: pointer;
}样式设置:
#box 元素设置了左右 20 像素的内边距。#box 内 .list 类的 li 元素下的 span 元素: span 元素有 50 像素的宽度,右侧有 1 像素的灰色边框,右边距为 10 像素。span 元素有 30 像素的宽度,有一个背景图片,右浮动,右边距为 20 像素,鼠标悬停时有指针样式。#box 内 .list 类的 li 元素下最后一个 li 元素中的 b 元素: b 元素左浮动。b 元素右浮动,有指针样式。四、工作流程 ▶️ 1. 页面加载阶段: 当用户打开页面时,浏览器会解析 HTML 代码。
css/style.css 文件,根据其中的样式规则对页面元素进行初始样式设置。js/vue.js 文件,这是 Vue 框架的核心库,为页面的动态交互提供支持。<script> 标签内的 Vue 实例代码,创建 Vue 实例。2. Vue 实例初始化阶段: Vue 实例创建:
el: "#box" 确定管理的范围,即 id 为 box 的元素及其内部元素。data 中的属性: todos 数组初始化为 ['学习', '吃饭', '睡觉'],代表已有的任务列表。newTodo 初始化为空字符串,用于存储用户输入的新任务。methods 中的函数,为后续的交互操作提供处理逻辑。3. 用户交互阶段:
v-model 指令实时存储在 newTodo 中。id 为 add 的 span 元素)时,触发 addTodo() 方法: addTodo() 方法会检查 newTodo 经过 trim() 处理后是否不为空。newTodo 的内容添加到 todos 数组末尾。newTodo 重置为空,以便用户继续输入新任务。todos 数组发生了变化,触发重新渲染,使用 v-for 指令更新任务列表,根据 todos 的新长度显示新的任务列表项。class 为 qc 的 span 元素)。removeTodo(index) 方法,传递相应的 index 参数。removeTodo(index) 方法使用 splice() 从 todos 数组中删除指定 index 的元素。todos 数组的变化,Vue 会自动更新页面,将相应的任务列表项从页面上移除。id 为 clear 的 b 元素)时,触发 clearTodos() 方法。clearTodos() 方法将 todos 数组设置为空数组。todos 数组长度为 0,会显示 “暂无数据”,或根据 v-if 指令隐藏任务列表和总数信息。 4. 页面更新阶段:
当 data 中的数据发生变化(如 todos 数组或 newTodo 的变化)时,Vue 会自动进行虚拟 DOM 比较。
v-for 指令和 :key 绑定的 index 来更新列表项。整个工作流程是一个不断循环的过程,用户可以持续添加、删除或清除任务,Vue 会自动根据数据的变化更新页面,实现动态交互。
