Heife 2 months ago
parent c8daf566e4
commit 71018562c8

@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"sf_HW2/src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,43 @@
{
"name": "hw2-front",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"core-js": "^3.8.3",
"vue": "^3.2.13"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

@ -0,0 +1,32 @@
<template>
<div class="app-container">
<ToDoList />
</div>
</template>
<script setup>
import ToDoList from "./components/ToDoList.vue";
</script>
<style>
/* 移除 scoped使用全局样式 */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
html, body {
height: 100%;
}
.app-container {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #F3F4F4;
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

@ -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>

@ -0,0 +1,4 @@
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
Loading…
Cancel
Save