工作台界面-初版

This commit is contained in:
Cheng Zhou
2025-12-17 22:37:51 +08:00
parent c50ca05099
commit ad4fa6ae7a
13 changed files with 685 additions and 75 deletions
@@ -0,0 +1,108 @@
<template>
<el-card shadow="never" class="todo-card">
<div class="section-header">
<span>个人待办本地</span>
</div>
<div class="input-row">
<el-input v-model="input" placeholder="记录一个备忘..." @keyup.enter.native="add" />
<el-button type="primary" @click="add">添加</el-button>
</div>
<div v-if="todos.length" class="todo-list">
<div v-for="item in todos" :key="item.id" class="todo-item">
<el-checkbox v-model="item.done" @change="save">{{ item.text }}</el-checkbox>
<el-button link type="danger" size="small" @click="remove(item.id)">删除</el-button>
</div>
</div>
<div v-else class="empty">暂无待办可添加你的个人备忘</div>
</el-card>
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from "vue";
const props = defineProps<{ storageKey: string | undefined }>();
interface TodoItem {
id: string;
text: string;
done: boolean;
}
const input = ref("");
const todos = ref<TodoItem[]>([]);
const load = () => {
if (!props.storageKey) return;
const raw = localStorage.getItem(props.storageKey);
if (raw) {
try {
todos.value = JSON.parse(raw) || [];
} catch {
todos.value = [];
}
}
};
const save = () => {
if (!props.storageKey) return;
localStorage.setItem(props.storageKey, JSON.stringify(todos.value));
};
const add = () => {
const text = input.value.trim();
if (!text) return;
todos.value.unshift({
id: crypto.randomUUID ? crypto.randomUUID() : Date.now().toString(),
text,
done: false,
});
input.value = "";
save();
};
const remove = (id: string) => {
todos.value = todos.value.filter((t) => t.id !== id);
save();
};
watch(
() => props.storageKey,
() => load(),
{ immediate: true }
);
onMounted(() => {
load();
});
</script>
<style scoped>
.todo-card {
min-height: 200px;
}
.section-header {
font-weight: 600;
margin-bottom: 8px;
}
.input-row {
display: flex;
gap: 8px;
margin-bottom: 8px;
}
.todo-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.todo-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 8px;
border: 1px solid #ebeef5;
border-radius: 6px;
}
.empty {
color: #888;
}
</style>