deotalandAi/apps/FrontendDesigner/src/views/Home.vue

500 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup>
import { ref, computed, onMounted } from 'vue'
import { useI18n } from '../composables/useI18n'
import { useTheme } from '../composables/useTheme'
// 国际化
const { t } = useI18n()
// 主题系统
const { currentTheme } = useTheme()
// 数据
const features = ref([
{
icon: '🎨',
title: '响应式设计',
description: '支持移动端、平板和桌面端的完美适配'
},
{
icon: '🌍',
title: '国际化支持',
description: '内置中英文切换,支持扩展更多语言'
},
{
icon: '🌓',
title: '主题切换',
description: '支持浅色、深色和高对比度主题模式'
},
{
icon: '⚡',
title: 'Vue 3 + Vite',
description: '基于最新技术栈,性能优化,开发效率高'
},
{
icon: '🎯',
title: '组件化开发',
description: '遵循Vue 3最佳实践代码结构清晰'
},
{
icon: '🔧',
title: '开发工具链',
description: '集成ESLint、Prettier等现代化工具'
}
])
const stats = ref([
{ label: '技术栈', value: 'Vue 3 + Vite' },
{ label: '语言支持', value: '中英双语' },
{ label: '响应式断点', value: '3个主要断点' },
{ label: '主题模式', value: '3种主题' }
])
// 计算属性
const heroTitle = computed(() => t('welcome.title'))
const heroSubtitle = computed(() => t('welcome.subtitle'))
const heroDescription = computed(() => t('welcome.description'))
</script>
<template>
<div class="home-page">
<!-- 英雄区域 -->
<section class="hero-section">
<div class="hero-container">
<div class="hero-content">
<h1 class="hero-title">{{ heroTitle }}</h1>
<p class="hero-subtitle">{{ heroSubtitle }}</p>
<p class="hero-description">{{ heroDescription }}</p>
<div class="hero-actions">
<button class="btn btn-primary">
{{ t('welcome.start') }}
</button>
<button class="btn btn-secondary">
查看文档
</button>
</div>
</div>
<div class="hero-visual">
<div class="visual-card">
<div class="visual-header">
<div class="visual-dots">
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="visual-content">
<div class="visual-line"></div>
<div class="visual-line short"></div>
<div class="visual-line medium"></div>
<div class="visual-blocks">
<div class="block"></div>
<div class="block"></div>
<div class="block"></div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- 特性展示 -->
<section class="features-section">
<div class="section-container">
<h2 class="section-title">{{ t('welcome.features') }}</h2>
<div class="features-grid">
<div
v-for="feature in features"
:key="feature.title"
class="feature-card"
>
<div class="feature-icon">{{ feature.icon }}</div>
<h3 class="feature-title">{{ feature.title }}</h3>
<p class="feature-description">{{ feature.description }}</p>
</div>
</div>
</div>
</section>
<!-- 统计数据 -->
<section class="stats-section">
<div class="section-container">
<h2 class="section-title">项目亮点</h2>
<div class="stats-grid">
<div
v-for="stat in stats"
:key="stat.label"
class="stat-item"
>
<div class="stat-value">{{ stat.value }}</div>
<div class="stat-label">{{ stat.label }}</div>
</div>
</div>
</div>
</section>
<!-- 技术栈展示 -->
<section class="tech-section">
<div class="section-container">
<h2 class="section-title">技术栈</h2>
<div class="tech-stack">
<div class="tech-item">
<img src="/vite.svg" alt="Vite" class="tech-logo" />
<span class="tech-name">Vite</span>
</div>
<div class="tech-item">
<img src="https://vuejs.org/logo.svg" alt="Vue 3" class="tech-logo" />
<span class="tech-name">Vue 3</span>
</div>
<div class="tech-item">
<div class="tech-icon">🗃️</div>
<span class="tech-name">Pinia</span>
</div>
<div class="tech-item">
<div class="tech-icon">🛣️</div>
<span class="tech-name">Vue Router</span>
</div>
<div class="tech-item">
<div class="tech-icon">🌍</div>
<span class="tech-name">Vue I18n</span>
</div>
</div>
</div>
</section>
</div>
</template>
<style scoped>
.home-page {
min-height: 100%;
}
/* 英雄区域 */
.hero-section {
padding: var(--spacing-2xl) 0;
background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%);
}
.hero-container {
max-width: var(--container-max-width);
margin: 0 auto;
padding: 0 var(--spacing-lg);
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--spacing-2xl);
align-items: center;
}
.hero-content {
max-width: 500px;
}
.hero-title {
font-size: var(--font-size-4xl);
font-weight: 800;
color: var(--text-primary);
margin: 0 0 var(--spacing-md) 0;
line-height: 1.2;
}
.hero-subtitle {
font-size: var(--font-size-xl);
font-weight: 600;
color: var(--text-secondary);
margin: 0 0 var(--spacing-md) 0;
}
.hero-description {
font-size: var(--font-size-lg);
color: var(--text-muted);
margin: 0 0 var(--spacing-xl) 0;
line-height: 1.6;
}
.hero-actions {
display: flex;
gap: var(--spacing-md);
flex-wrap: wrap;
}
/* 按钮样式 */
.btn {
padding: var(--spacing-md) var(--spacing-xl);
border: none;
border-radius: var(--border-radius-lg);
font-size: var(--font-size-md);
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
text-decoration: none;
display: inline-block;
text-align: center;
}
.btn-primary {
background-color: var(--primary-color);
color: white;
}
.btn-primary:hover {
background-color: var(--primary-color-hover);
transform: translateY(-2px);
box-shadow: var(--shadow-lg);
}
.btn-secondary {
background-color: transparent;
color: var(--text-primary);
border: 2px solid var(--border-color);
}
.btn-secondary:hover {
background-color: var(--bg-secondary);
border-color: var(--text-secondary);
}
/* 可视化卡片 */
.hero-visual {
display: flex;
justify-content: center;
align-items: center;
}
.visual-card {
background-color: var(--bg-secondary);
border-radius: var(--border-radius-xl);
padding: var(--spacing-lg);
box-shadow: var(--shadow-xl);
width: 300px;
max-width: 100%;
}
.visual-header {
display: flex;
align-items: center;
margin-bottom: var(--spacing-md);
}
.visual-dots {
display: flex;
gap: var(--spacing-xs);
}
.visual-dots span {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: var(--text-muted);
}
.visual-dots span:nth-child(1) { background-color: #ff5f56; }
.visual-dots span:nth-child(2) { background-color: #ffbd2e; }
.visual-dots span:nth-child(3) { background-color: #27ca3f; }
.visual-content {
display: flex;
flex-direction: column;
gap: var(--spacing-sm);
}
.visual-line {
height: 4px;
background-color: var(--primary-color);
border-radius: 2px;
opacity: 0.7;
}
.visual-line.short {
width: 60%;
}
.visual-line.medium {
width: 80%;
}
.visual-blocks {
display: flex;
gap: var(--spacing-xs);
margin-top: var(--spacing-sm);
}
.block {
flex: 1;
height: 60px;
background-color: var(--bg-tertiary);
border-radius: var(--border-radius-md);
border: 1px solid var(--border-color);
}
/* 特性区域 */
.features-section {
padding: var(--spacing-2xl) 0;
background-color: var(--bg-primary);
}
.section-container {
max-width: var(--container-max-width);
margin: 0 auto;
padding: 0 var(--spacing-lg);
}
.section-title {
font-size: var(--font-size-3xl);
font-weight: 700;
text-align: center;
color: var(--text-primary);
margin: 0 0 var(--spacing-xl) 0;
}
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: var(--spacing-xl);
}
.feature-card {
background-color: var(--bg-secondary);
padding: var(--spacing-xl);
border-radius: var(--border-radius-xl);
text-align: center;
transition: all 0.3s ease;
border: 1px solid var(--border-color);
}
.feature-card:hover {
transform: translateY(-4px);
box-shadow: var(--shadow-xl);
border-color: var(--primary-color);
}
.feature-icon {
font-size: 3rem;
margin-bottom: var(--spacing-md);
}
.feature-title {
font-size: var(--font-size-lg);
font-weight: 600;
color: var(--text-primary);
margin: 0 0 var(--spacing-sm) 0;
}
.feature-description {
color: var(--text-secondary);
line-height: 1.6;
margin: 0;
}
/* 统计数据 */
.stats-section {
padding: var(--spacing-2xl) 0;
background-color: var(--bg-secondary);
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: var(--spacing-xl);
}
.stat-item {
text-align: center;
padding: var(--spacing-lg);
}
.stat-value {
font-size: var(--font-size-2xl);
font-weight: 700;
color: var(--primary-color);
margin-bottom: var(--spacing-xs);
}
.stat-label {
color: var(--text-secondary);
font-weight: 500;
}
/* 技术栈 */
.tech-section {
padding: var(--spacing-2xl) 0;
background-color: var(--bg-primary);
}
.tech-stack {
display: flex;
justify-content: center;
align-items: center;
gap: var(--spacing-xl);
flex-wrap: wrap;
}
.tech-item {
display: flex;
flex-direction: column;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-lg);
background-color: var(--bg-secondary);
border-radius: var(--border-radius-lg);
transition: all 0.2s ease;
}
.tech-item:hover {
transform: scale(1.05);
box-shadow: var(--shadow-lg);
}
.tech-logo {
width: 48px;
height: 48px;
object-fit: contain;
}
.tech-icon {
font-size: 48px;
text-align: center;
}
.tech-name {
font-weight: 600;
color: var(--text-secondary);
font-size: var(--font-size-sm);
}
/* 响应式设计 */
@media (max-width: 768px) {
.hero-container {
grid-template-columns: 1fr;
text-align: center;
gap: var(--spacing-xl);
}
.hero-title {
font-size: var(--font-size-3xl);
}
.hero-subtitle {
font-size: var(--font-size-lg);
}
.hero-actions {
justify-content: center;
}
.features-grid {
grid-template-columns: 1fr;
}
.stats-grid {
grid-template-columns: repeat(2, 1fr);
}
.tech-stack {
gap: var(--spacing-md);
}
.tech-item {
padding: var(--spacing-md);
}
}
</style>