|
|
|
@ -0,0 +1,442 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="todo-list-container">
|
|
|
|
|
<!-- To-Do List 的标题 -->
|
|
|
|
|
<h1 class="todo-list-title">To-Do List</h1>
|
|
|
|
|
|
|
|
|
|
<!-- 添加新任务的区域 -->
|
|
|
|
|
<div class="add-todo">
|
|
|
|
|
<p class="add-todo-text">What needs to be done?</p>
|
|
|
|
|
<!-- 输入框:用于输入新任务的名称 -->
|
|
|
|
|
<input class="add-todo-input" v-model="inputText" />
|
|
|
|
|
<!-- 按钮:点击后将新任务添加到列表中 -->
|
|
|
|
|
<button class="add-todo-button" type="submit" @click="addToDo">Add</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 任务列表区域 -->
|
|
|
|
|
<div class="todo-list">
|
|
|
|
|
<!-- 显示已完成和总任务数的统计 -->
|
|
|
|
|
<p class="todo-list-complete-text">{{ completedToDo }} out of {{ totalToDo }} items completed</p>
|
|
|
|
|
|
|
|
|
|
<!-- 循环渲染每个任务项 -->
|
|
|
|
|
<div
|
|
|
|
|
v-for="(item, index) in toDoList"
|
|
|
|
|
:key="index"
|
|
|
|
|
class="todo-item-container"
|
|
|
|
|
>
|
|
|
|
|
<!-- 显示任务详情(非编辑模式) -->
|
|
|
|
|
<div v-if="!item.isEditing" class="todo-item-view">
|
|
|
|
|
<div class="todo-item-view-top">
|
|
|
|
|
<!-- 复选框:标记任务是否完成 -->
|
|
|
|
|
<input
|
|
|
|
|
type="checkbox"
|
|
|
|
|
class="todo-item-checkbox"
|
|
|
|
|
v-model="item.completed"
|
|
|
|
|
/>
|
|
|
|
|
<!-- 任务名称:根据完成状态显示不同样式 -->
|
|
|
|
|
<span
|
|
|
|
|
:class="[
|
|
|
|
|
'todo-item-text',
|
|
|
|
|
{ 'completed-text': item.completed }
|
|
|
|
|
]"
|
|
|
|
|
>
|
|
|
|
|
{{ item.text }}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="todo-item-view-bottom">
|
|
|
|
|
<!-- 编辑按钮:点击后进入编辑模式 -->
|
|
|
|
|
<button class="todo-item-button edit" @click="editToDo(item)">
|
|
|
|
|
Edit
|
|
|
|
|
</button>
|
|
|
|
|
<!-- 删除按钮:点击后删除该任务 -->
|
|
|
|
|
<button class="todo-item-button delete" @click="deleteToDo(index)">
|
|
|
|
|
Delete
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 编辑任务详情(编辑模式) -->
|
|
|
|
|
<div v-else class="todo-item-edit">
|
|
|
|
|
<!-- 编辑提示文本 -->
|
|
|
|
|
<p class="add-item-edit-text">Edit Name for "{{ item.text }}"</p>
|
|
|
|
|
<!-- 输入框:用于编辑任务名称 -->
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
class="todo-item-edit-input"
|
|
|
|
|
v-model="item.editText"
|
|
|
|
|
/>
|
|
|
|
|
<div class="todo-item-edit-actions">
|
|
|
|
|
<!-- 取消按钮:退出编辑模式 -->
|
|
|
|
|
<button class="todo-item-button-cancel" @click="cancelEdit(item)">
|
|
|
|
|
Cancel
|
|
|
|
|
</button>
|
|
|
|
|
<!-- 保存按钮:保存编辑后的任务名称 -->
|
|
|
|
|
<button class="todo-item-button-save" @click="saveEdit(item)">
|
|
|
|
|
Save
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
import { ref, computed } from 'vue';
|
|
|
|
|
|
|
|
|
|
// 任务列表:使用 ref 创建响应式数组,存储所有任务项
|
|
|
|
|
const toDoList = ref([]);
|
|
|
|
|
|
|
|
|
|
// 输入框文本:使用 ref 创建响应式变量,绑定添加任务的输入框
|
|
|
|
|
const inputText = ref('');
|
|
|
|
|
|
|
|
|
|
// 添加新任务的方法
|
|
|
|
|
const addToDo = () => {
|
|
|
|
|
// 创建新任务对象,包含任务文本、完成状态和编辑状态
|
|
|
|
|
const newToDo = {
|
|
|
|
|
text: inputText.value,
|
|
|
|
|
completed: false,
|
|
|
|
|
isEditing: false
|
|
|
|
|
};
|
|
|
|
|
// 将新任务添加到任务列表
|
|
|
|
|
toDoList.value.push(newToDo);
|
|
|
|
|
// 清空输入框内容
|
|
|
|
|
inputText.value = '';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 计算属性:统计总任务数
|
|
|
|
|
const totalToDo = computed(() => {
|
|
|
|
|
return toDoList.value.length;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 计算属性:统计已完成任务数
|
|
|
|
|
const completedToDo = computed(() => {
|
|
|
|
|
return toDoList.value.filter((item) => item.completed).length;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 删除任务的方法
|
|
|
|
|
const deleteToDo = (index) => {
|
|
|
|
|
// 根据索引从任务列表中移除指定任务
|
|
|
|
|
toDoList.value.splice(index, 1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 编辑任务的方法
|
|
|
|
|
const editToDo = (item) => {
|
|
|
|
|
// 进入编辑模式,并备份当前任务文本到 editText
|
|
|
|
|
item.isEditing = true;
|
|
|
|
|
item.editText = item.text;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 取消编辑的方法
|
|
|
|
|
const cancelEdit = (item) => {
|
|
|
|
|
// 退出编辑模式,不保存更改
|
|
|
|
|
item.isEditing = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 保存编辑的方法
|
|
|
|
|
const saveEdit = (item) => {
|
|
|
|
|
// 将编辑后的文本更新到任务名称并退出编辑模式
|
|
|
|
|
item.text = item.editText;
|
|
|
|
|
item.isEditing = false;
|
|
|
|
|
};
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
/* To-Do List 容器样式 */
|
|
|
|
|
.todo-list-container {
|
|
|
|
|
width: 400px; /* 固定宽度 */
|
|
|
|
|
min-height: 500px; /* 最小高度 */
|
|
|
|
|
max-height: 500px; /* 最大高度 */
|
|
|
|
|
background-color: #FFFFFF; /* 白色背景 */
|
|
|
|
|
border-radius: 2px; /* 圆角 */
|
|
|
|
|
padding: 20px; /* 内边距 */
|
|
|
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); /* 阴影效果 */
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column; /* 垂直布局 */
|
|
|
|
|
gap: 0.2rem; /* 子元素间距 */
|
|
|
|
|
align-items: center; /* 水平居中 */
|
|
|
|
|
overflow-y: hidden; /* 隐藏垂直溢出 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 标题样式 */
|
|
|
|
|
.todo-list-title {
|
|
|
|
|
color: #5E4E4E; /* 深灰褐色文字 */
|
|
|
|
|
font-size: 1.8rem; /* 字体大小 */
|
|
|
|
|
margin-top: 15px; /* 上边距 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 添加任务区域样式 */
|
|
|
|
|
.add-todo {
|
|
|
|
|
width: 100%; /* 占满容器宽度 */
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column; /* 垂直布局 */
|
|
|
|
|
align-items: center; /* 水平居中 */
|
|
|
|
|
margin-bottom: 20px; /* 下边距 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 添加任务提示文本样式 */
|
|
|
|
|
.add-todo-text {
|
|
|
|
|
color: #4F4F4F; /* 中灰色文字 */
|
|
|
|
|
margin-bottom: 2px; /* 下边距 */
|
|
|
|
|
font-size: 0.8rem; /* 字体大小 */
|
|
|
|
|
font-weight: 600; /* 字体加粗 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 添加任务输入框样式 */
|
|
|
|
|
.add-todo-input {
|
|
|
|
|
width: 100%; /* 占满容器宽度 */
|
|
|
|
|
padding: 8px; /* 内边距 */
|
|
|
|
|
height: 30px; /* 固定高度 */
|
|
|
|
|
margin-bottom: 10px; /* 下边距 */
|
|
|
|
|
border: 1px solid #ccc; /* 边框 */
|
|
|
|
|
border-radius: 1px; /* 圆角 */
|
|
|
|
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(0, 0, 0, 0.1); /* 内阴影和外阴影 */
|
|
|
|
|
border-top: #9E9E9E 1px solid; /* 顶部边框颜色 */
|
|
|
|
|
border-left: #E5E6E6 0.5px solid; /* 左侧边框颜色 */
|
|
|
|
|
border-right: #E5E6E6 0.5px solid; /* 右侧边框颜色 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 添加任务按钮样式 */
|
|
|
|
|
.add-todo-button {
|
|
|
|
|
width: 100%; /* 占满容器宽度 */
|
|
|
|
|
padding: 8px; /* 内边距 */
|
|
|
|
|
background-color: #000000; /* 黑色背景 */
|
|
|
|
|
color: #FFFFFF; /* 白色文字 */
|
|
|
|
|
border: none; /* 无边框 */
|
|
|
|
|
border-radius: 1px; /* 圆角 */
|
|
|
|
|
cursor: pointer; /* 鼠标指针 */
|
|
|
|
|
transition: all 0.3s ease; /* 过渡效果 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 添加任务按钮悬停样式 */
|
|
|
|
|
.add-todo-button:hover {
|
|
|
|
|
background-color: #e0e0e0; /* 浅灰色背景 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务列表样式 */
|
|
|
|
|
.todo-list {
|
|
|
|
|
width: 85%; /* 占容器宽度的85% */
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column; /* 垂直布局 */
|
|
|
|
|
align-items: flex-start; /* 左对齐 */
|
|
|
|
|
overflow-y: auto; /* 垂直滚动 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务完成统计文本样式 */
|
|
|
|
|
.todo-list-complete-text {
|
|
|
|
|
color: #5E4E4E; /* 深灰褐色文字 */
|
|
|
|
|
font-size: 0.9rem; /* 字体大小 */
|
|
|
|
|
font-weight: 600; /* 字体加粗 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项容器样式 */
|
|
|
|
|
.todo-item-container {
|
|
|
|
|
width: 100%; /* 占满容器宽度 */
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column; /* 垂直布局 */
|
|
|
|
|
margin-top: 10px; /* 上边距 */
|
|
|
|
|
margin-bottom: 10px; /* 下边距 */
|
|
|
|
|
border-bottom: 1px solid #E5E6E6; /* 底部边框 */
|
|
|
|
|
padding-bottom: 8px; /* 底部内边距 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项视图样式(非编辑模式) */
|
|
|
|
|
.todo-item-view {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column; /* 垂直布局 */
|
|
|
|
|
align-items: flex-start; /* 左对齐 */
|
|
|
|
|
width: 100%; /* 占满容器宽度 */
|
|
|
|
|
gap: 6px; /* 子元素间距 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项顶部样式 */
|
|
|
|
|
.todo-item-view-top {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center; /* 垂直居中 */
|
|
|
|
|
justify-content: flex-start; /* 左对齐 */
|
|
|
|
|
gap: 10px; /* 子元素间距 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项编辑样式(编辑模式) */
|
|
|
|
|
.todo-item-edit {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column; /* 垂直布局 */
|
|
|
|
|
align-items: flex-start; /* 左对齐 */
|
|
|
|
|
gap: 6px; /* 子元素间距 */
|
|
|
|
|
background: white; /* 白色背景 */
|
|
|
|
|
width: 100%; /* 占满容器宽度 */
|
|
|
|
|
padding: 6px; /* 内边距 */
|
|
|
|
|
border: none; /* 无边框 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 复选框样式 */
|
|
|
|
|
.todo-item-checkbox {
|
|
|
|
|
cursor: pointer; /* 鼠标指针 */
|
|
|
|
|
border-radius: 0; /* 无圆角 */
|
|
|
|
|
width: 20px; /* 宽度 */
|
|
|
|
|
height: 20px; /* 高度 */
|
|
|
|
|
border: #000000 4px solid; /* 黑色边框 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项文本样式 */
|
|
|
|
|
.todo-item-text {
|
|
|
|
|
font-size: 0.7rem; /* 字体大小 */
|
|
|
|
|
font-weight: 600; /* 字体加粗 */
|
|
|
|
|
color: #5E2626; /* 深红褐色文字 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 已完成任务的文本样式 */
|
|
|
|
|
.completed-text {
|
|
|
|
|
text-decoration: line-through; /* 删除线 */
|
|
|
|
|
color: #999; /* 灰色文字 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项底部样式 */
|
|
|
|
|
.todo-item-view-bottom {
|
|
|
|
|
width: 100%; /* 占满容器宽度 */
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center; /* 垂直居中 */
|
|
|
|
|
justify-content: flex-start; /* 左对齐 */
|
|
|
|
|
gap: 10px; /* 子元素间距 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项按钮通用样式 */
|
|
|
|
|
.todo-item-button {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center; /* 垂直居中 */
|
|
|
|
|
justify-content: center; /* 水平居中 */
|
|
|
|
|
width: 50%; /* 宽度占50% */
|
|
|
|
|
height: 30px; /* 固定高度 */
|
|
|
|
|
padding: 6px 12px; /* 内边距 */
|
|
|
|
|
background-color: #000000; /* 黑色背景 */
|
|
|
|
|
color: #FFFFFF; /* 白色文字 */
|
|
|
|
|
border: none; /* 无边框 */
|
|
|
|
|
border-radius: 1px; /* 圆角 */
|
|
|
|
|
cursor: pointer; /* 鼠标指针 */
|
|
|
|
|
transition: all 0.3s ease; /* 过渡效果 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 编辑按钮样式 */
|
|
|
|
|
.edit {
|
|
|
|
|
color: #4D9F9F; /* 青色文字 */
|
|
|
|
|
background: white; /* 白色背景 */
|
|
|
|
|
border: 1px solid #4D9F9F; /* 青色边框 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 删除按钮样式 */
|
|
|
|
|
.delete {
|
|
|
|
|
color: white; /* 白色文字 */
|
|
|
|
|
background: #BE4B41; /* 红色背景 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项按钮悬停样式 */
|
|
|
|
|
.todo-item-button:hover {
|
|
|
|
|
background-color: #e0e0e0; /* 浅灰色背景 */
|
|
|
|
|
color: #000000; /* 黑色文字 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 编辑提示文本样式 */
|
|
|
|
|
.add-item-edit-text {
|
|
|
|
|
color: #5E4E4E; /* 深灰褐色文字 */
|
|
|
|
|
font-weight: 500; /* 字体中等粗细 */
|
|
|
|
|
font-size: 0.8rem; /* 字体大小 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项编辑输入框样式 */
|
|
|
|
|
.todo-item-edit-input {
|
|
|
|
|
width: 100%; /* 占满容器宽度 */
|
|
|
|
|
padding: 6px; /* 内边距 */
|
|
|
|
|
border: 1px solid #ccc; /* 边框 */
|
|
|
|
|
border-radius: 1px; /* 圆角 */
|
|
|
|
|
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(0, 0, 0, 0.1); /* 内阴影和外阴影 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 任务项编辑操作按钮组样式 */
|
|
|
|
|
.todo-item-edit-actions {
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 6px; /* 子元素间距 */
|
|
|
|
|
width: 100%; /* 占满容器宽度 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 取消按钮样式 */
|
|
|
|
|
.todo-item-button-cancel {
|
|
|
|
|
width: 45%; /* 宽度占45% */
|
|
|
|
|
padding: 6px 12px; /* 内边距 */
|
|
|
|
|
background-color: #FFFFFF; /* 白色背景 */
|
|
|
|
|
color: #000000; /* 黑色文字 */
|
|
|
|
|
border: 1px solid #000000; /* 黑色边框 */
|
|
|
|
|
border-radius: 1px; /* 圆角 */
|
|
|
|
|
cursor: pointer; /* 鼠标指针 */
|
|
|
|
|
transition: all 0.3s ease; /* 过渡效果 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 取消按钮悬停样式 */
|
|
|
|
|
.todo-item-button-cancel:hover {
|
|
|
|
|
background-color: #e0e0e0; /* 浅灰色背景 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 保存按钮样式 */
|
|
|
|
|
.todo-item-button-save {
|
|
|
|
|
width: 45%; /* 宽度占45% */
|
|
|
|
|
padding: 6px 12px; /* 内边距 */
|
|
|
|
|
background-color: #000000; /* 黑色背景 */
|
|
|
|
|
color: #FFFFFF; /* 白色文字 */
|
|
|
|
|
border: none; /* 无边框 */
|
|
|
|
|
border-radius: 1px; /* 圆角 */
|
|
|
|
|
cursor: pointer; /* 鼠标指针 */
|
|
|
|
|
transition: all 0.3s ease; /* 过渡效果 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 保存按钮悬停样式 */
|
|
|
|
|
.todo-item-button-save:hover {
|
|
|
|
|
background-color: #e0e0e0; /* 浅灰色背景 */
|
|
|
|
|
color: #000000; /* 黑色文字 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 输入框聚焦样式 */
|
|
|
|
|
.add-todo-input:focus,
|
|
|
|
|
.todo-item-edit-input:focus {
|
|
|
|
|
outline: none; /* 移除默认轮廓 */
|
|
|
|
|
border-color: #9E9E9E; /* 边框颜色变为灰色 */
|
|
|
|
|
box-shadow: 0 0 3px #999; /* 聚焦时阴影效果 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 输入框过渡效果 */
|
|
|
|
|
.add-todo-input,
|
|
|
|
|
.todo-item-edit-input {
|
|
|
|
|
transition: box-shadow 0.3s, border-color 0.3s; /* 阴影和边框颜色过渡 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 按钮悬停时的阴影效果 */
|
|
|
|
|
.add-todo-button:hover,
|
|
|
|
|
.todo-item-button:hover,
|
|
|
|
|
.todo-item-button-cancel:hover,
|
|
|
|
|
.todo-item-button-save:hover {
|
|
|
|
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); /* 添加阴影 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 按钮激活时的样式 */
|
|
|
|
|
.add-todo-button:active,
|
|
|
|
|
.todo-item-button:active,
|
|
|
|
|
.todo-item-button-cancel:active,
|
|
|
|
|
.todo-item-button-save:active {
|
|
|
|
|
background-color: #cccccc; /* 灰色背景 */
|
|
|
|
|
transform: scale(0.98); /* 轻微缩小效果 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 按钮聚焦时的样式 */
|
|
|
|
|
.add-todo-button:focus,
|
|
|
|
|
.todo-item-button:focus,
|
|
|
|
|
.todo-item-button-cancel:focus,
|
|
|
|
|
.todo-item-button-save:focus {
|
|
|
|
|
outline: 2px solid #000000; /* 黑色轮廓 */
|
|
|
|
|
outline-offset: 2px; /* 轮廓偏移 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 按钮过渡效果 */
|
|
|
|
|
.add-todo-button,
|
|
|
|
|
.todo-item-button,
|
|
|
|
|
.todo-item-button-cancel,
|
|
|
|
|
.todo-item-button-save {
|
|
|
|
|
transition: background-color 0.3s, color 0.3s, transform 0.1s, box-shadow 0.3s; /* 多属性过渡 */
|
|
|
|
|
}
|
|
|
|
|
</style>
|