123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- <template>
- <div class="max-w-2xl mx-auto p-6 text-center">
- <h1 class="text-2xl font-bold mb-6">随机名言生成器</h1>
-
- <!-- 分类选择 -->
- <div class="mb-6">
- <select
- v-model="selectedCategory"
- class="px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary"
- >
- <option value="all">所有分类</option>
- <option value="motivation">励志</option>
- <option value="life">生活</option>
- <option value="love">爱情</option>
- <option value="friendship">友情</option>
- <option value="success">成功</option>
- </select>
- </div>
-
- <!-- 名言卡片 -->
- <div
- v-if="currentQuote"
- class="bg-white rounded-xl shadow-lg p-8 mb-6 transition-opacity duration-500"
- :class="{ 'opacity-0': isLoading }"
- >
- <div class="text-2xl font-light mb-4 italic">
- "{{ currentQuote.text }}"
- </div>
- <div class="text-right font-medium">
- —— {{ currentQuote.author }}
- </div>
- <div class="mt-4 text-sm text-gray-500">
- 分类: {{ getCategoryName(currentQuote.category) }}
- </div>
- </div>
-
- <!-- 加载状态 -->
- <div v-if="isLoading" class="mb-6 text-gray-500">
- <div class="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-primary mb-2"></div>
- <p>加载中...</p>
- </div>
-
- <!-- 按钮 -->
- <button
- @click="fetchQuote"
- class="bg-primary text-white px-6 py-3 rounded-lg hover:bg-primary/90 transition-colors shadow-md hover:shadow-lg"
- >
- 获取新名言
- </button>
- </div>
- </template>
- <script setup lang="ts">
- import { ref, reactive, onMounted } from 'vue';
- // 名言接口
- interface Quote {
- text: string;
- author: string;
- category: QuoteCategory;
- }
- type QuoteCategory = 'motivation' | 'life' | 'love' | 'friendship' | 'success';
- // 模拟名言数据
- const mockQuotes: Quote[] = [
- {
- text: "成功不是终点,失败也并非末日,重要的是继续前进的勇气。",
- author: "温斯顿·丘吉尔",
- category: "motivation"
- },
- {
- text: "生活不是等待暴风雨过去,而是学会在雨中跳舞。",
- author: "维维安·格林",
- category: "life"
- },
- {
- text: "爱是当你遇到某个人,他的幸福比你自己的更重要。",
- author: "H.杰克逊·布朗",
- category: "love"
- },
- {
- text: "真正的朋友是那些在你光芒四射时出现,却在你落魄时留下的人。",
- author: "沃尔特·温切尔",
- category: "friendship"
- },
- {
- text: "成功就是从失败到失败,也依然不改热情。",
- author: "温斯顿·丘吉尔",
- category: "success"
- },
- {
- text: "不要等待机会,要创造机会。",
- author: "萧伯纳",
- category: "motivation"
- },
- {
- text: "生命中最美好的事情,往往是那些你从未计划过的。",
- author: "无名氏",
- category: "life"
- },
- {
- text: "爱情不是彼此凝视,而是一起注视同一个方向。",
- author: "安托万·德·圣埃克苏佩里",
- category: "love"
- },
- {
- text: "朋友是那个知道你所有缺点,却依然喜欢你的人。",
- author: "埃尔伯特·哈伯德",
- category: "friendship"
- },
- {
- text: "成功的秘诀在于始终如一地坚持目标。",
- author: "本杰明·迪斯雷利",
- category: "success"
- }
- ];
- // 状态管理
- const currentQuote = ref<Quote | null>(null);
- const isLoading = ref(false);
- const selectedCategory = ref<QuoteCategory | 'all'>('all');
- // 获取分类名称
- const getCategoryName = (category: QuoteCategory) => {
- const names: Record<QuoteCategory, string> = {
- motivation: '励志',
- life: '生活',
- love: '爱情',
- friendship: '友情',
- success: '成功'
- };
- return names[category];
- };
- // 获取随机名言
- const fetchQuote = () => {
- isLoading.value = true;
-
- // 模拟API请求延迟
- setTimeout(() => {
- let filteredQuotes = mockQuotes;
-
- // 如果选择了特定分类,过滤名言
- if (selectedCategory.value !== 'all') {
- filteredQuotes = mockQuotes.filter(quote =>
- quote.category === selectedCategory.value
- );
- }
-
- // 如果没有匹配的名言,使用全部名言
- if (filteredQuotes.length === 0) {
- filteredQuotes = mockQuotes;
- }
-
- // 随机选择一条名言
- const randomIndex = Math.floor(Math.random() * filteredQuotes.length);
- currentQuote.value = filteredQuotes[randomIndex];
-
- isLoading.value = false;
- }, 800);
- };
- // 组件挂载时获取第一条名言
- onMounted(() => {
- fetchQuote();
- });
- </script>
- <style scoped>
- /* 自定义样式 */
- </style>
|