Initial commit: WordLoop 单词学习应用

Vue 前端 + FastAPI 后端,含部署脚本与词典数据。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
John
2026-06-04 14:30:53 -07:00
commit bd7635986a
66 changed files with 5495 additions and 0 deletions
+62
View File
@@ -0,0 +1,62 @@
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'
import WordCard from '../components/WordCard.vue'
import { api, type Word } from '../api/request'
const tabs = [
{ key: '', label: '全部' },
{ key: 'new', label: '新词' },
{ key: 'learning', label: '学习中' },
{ key: 'mastered', label: '已掌握' },
{ key: 'weak', label: '易错词' },
]
const activeTab = ref('')
const words = ref<Word[]>([])
const loading = ref(true)
async function loadWords() {
loading.value = true
try {
const { data } = await api.listWords(activeTab.value || undefined)
words.value = data
} finally {
loading.value = false
}
}
async function handleDelete(id: number) {
if (!confirm('确定删除这个单词?')) return
await api.deleteWord(id)
await loadWords()
}
watch(activeTab, loadWords)
onMounted(loadWords)
</script>
<template>
<div class="page">
<h1 class="page-title">单词库</h1>
<div class="tabs">
<button
v-for="t in tabs"
:key="t.key"
:class="['tab', { active: activeTab === t.key }]"
@click="activeTab = t.key"
>
{{ t.label }}
</button>
</div>
<p v-if="loading" style="color: var(--muted)">加载中...</p>
<p v-else-if="words.length === 0" style="color: var(--muted); text-align: center">
暂无单词去翻译页添加吧
</p>
<WordCard
v-for="w in words"
:key="w.id"
:word="w"
@delete="handleDelete"
/>
</div>
</template>