fix: first commit
This commit is contained in:
parent
fb1bb099a0
commit
272ea70b3a
80
src/App.vue
80
src/App.vue
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<!-- 导航栏 -->
|
<!-- 导航栏 -->
|
||||||
<nav class="navbar">
|
<nav class="navbar" :class="{ 'navbar-hidden': isNavbarHidden }">
|
||||||
<div class="nav-container">
|
<div class="nav-container">
|
||||||
<div class="nav-brand">
|
<div class="nav-brand">
|
||||||
<span class="brand-text">智慧学习</span>
|
<span class="brand-text">智慧学习</span>
|
||||||
|
@ -61,6 +61,14 @@ import { RouterLink, RouterView } from 'vue-router'
|
||||||
// 下拉菜单状态
|
// 下拉菜单状态
|
||||||
const isDropdownOpen = ref(false)
|
const isDropdownOpen = ref(false)
|
||||||
|
|
||||||
|
// 导航栏隐藏状态
|
||||||
|
const isNavbarHidden = ref(false)
|
||||||
|
|
||||||
|
// 滚动相关变量
|
||||||
|
let lastScrollTop = 0
|
||||||
|
let scrollThreshold = 200 // 滚动阈值,超过这个距离才开始隐藏
|
||||||
|
let hideThreshold = 100 // 隐藏阈值,滚动超过这个距离时隐藏导航栏
|
||||||
|
|
||||||
// 切换下拉菜单
|
// 切换下拉菜单
|
||||||
const toggleDropdown = () => {
|
const toggleDropdown = () => {
|
||||||
isDropdownOpen.value = !isDropdownOpen.value
|
isDropdownOpen.value = !isDropdownOpen.value
|
||||||
|
@ -79,13 +87,34 @@ const handleClickOutside = (event) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理滚动事件
|
||||||
|
const handleScroll = () => {
|
||||||
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop
|
||||||
|
const windowHeight = window.innerHeight
|
||||||
|
const documentHeight = document.documentElement.scrollHeight
|
||||||
|
|
||||||
|
// 计算页面中心位置
|
||||||
|
const pageCenter = documentHeight / 2
|
||||||
|
|
||||||
|
// 如果滚动位置超过阈值且接近页面中心,则隐藏导航栏
|
||||||
|
if (scrollTop > scrollThreshold && scrollTop > pageCenter - windowHeight / 2) {
|
||||||
|
isNavbarHidden.value = true
|
||||||
|
} else {
|
||||||
|
isNavbarHidden.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollTop = scrollTop
|
||||||
|
}
|
||||||
|
|
||||||
// 生命周期钩子
|
// 生命周期钩子
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('click', handleClickOutside)
|
document.addEventListener('click', handleClickOutside)
|
||||||
|
window.addEventListener('scroll', handleScroll, { passive: true })
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
document.removeEventListener('click', handleClickOutside)
|
document.removeEventListener('click', handleClickOutside)
|
||||||
|
window.removeEventListener('scroll', handleScroll)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -105,6 +134,13 @@ onUnmounted(() => {
|
||||||
backdrop-filter: blur(20px);
|
backdrop-filter: blur(20px);
|
||||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
transition: all 0.3s ease;
|
transition: all 0.3s ease;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 导航栏隐藏状态 */
|
||||||
|
.navbar-hidden {
|
||||||
|
transform: translateY(-100%);
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-container {
|
.nav-container {
|
||||||
|
@ -290,41 +326,41 @@ onUnmounted(() => {
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
padding: 0.4rem 0.8rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
.brand-text {
|
.brand-text {
|
||||||
font-size: 1.25rem;
|
font-size: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-btn {
|
.login-btn {
|
||||||
padding: 0.5rem 1rem;
|
padding: 0.6rem 1.2rem;
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 480px) {
|
||||||
|
.nav-links {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-container {
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
.user-menu {
|
.user-menu {
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-trigger {
|
.dropdown-trigger {
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-menu {
|
.login-btn {
|
||||||
min-width: 150px;
|
padding: 0.5rem 1rem;
|
||||||
}
|
font-size: 0.8rem;
|
||||||
|
|
||||||
.dropdown-item {
|
|
||||||
padding: 0.75rem 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
.nav-links {
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
padding: 0.25rem 0.75rem;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import HomeView from '../views/HomeView.vue'
|
import HomeView from '../views/dashboard/HomeView.vue'
|
||||||
import LoginView from '../views/LoginView.vue'
|
import LoginView from '../views/auth/LoginView.vue'
|
||||||
import RegisterView from '../views/RegisterView.vue'
|
import RegisterView from '../views/auth/RegisterView.vue'
|
||||||
import NotificationsView from '../views/NotificationsView.vue'
|
import NotificationsView from '../views/profile/NotificationsView.vue'
|
||||||
import SettingsView from '../views/SettingsView.vue'
|
import SettingsView from '../views/profile/SettingsView.vue'
|
||||||
import CourseDetailView from '../views/CourseDetailView.vue'
|
import CourseDetailView from '../views/dashboard/CourseDetailView.vue'
|
||||||
import ProgressView from '../views/ProgressView.vue'
|
import ProgressView from '../views/learning/ProgressView.vue'
|
||||||
import ExamView from '../views/ExamView.vue'
|
import ExamView from '../views/dashboard/ExamView.vue'
|
||||||
import ResourcesView from '../views/ResourcesView.vue'
|
import ResourcesView from '../views/learning/ResourcesView.vue'
|
||||||
import ForumView from '../views/ForumView.vue'
|
import ForumView from '../views/social/ForumView.vue'
|
||||||
import PlanView from '../views/PlanView.vue'
|
import PlanView from '../views/learning/PlanView.vue'
|
||||||
import ProfileView from '../views/ProfileView.vue'
|
import ProfileView from '../views/profile/ProfileView.vue'
|
||||||
import HomeworkView from '../views/HomeworkView.vue'
|
import HomeworkView from '../views/dashboard/HomeworkView.vue'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
|
@ -24,22 +24,22 @@ const router = createRouter({
|
||||||
{
|
{
|
||||||
path: '/courses',
|
path: '/courses',
|
||||||
name: 'courses',
|
name: 'courses',
|
||||||
component: () => import('../views/CoursesView.vue'),
|
component: () => import('../views/dashboard/CoursesView.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/profile',
|
path: '/profile',
|
||||||
name: 'profile',
|
name: 'profile',
|
||||||
component: () => import('../views/ProfileView.vue'),
|
component: () => import('../views/profile/ProfileView.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/homework/:id',
|
path: '/homework/:id',
|
||||||
name: 'homework-detail',
|
name: 'homework-detail',
|
||||||
component: () => import('../views/HomeworkDetailView.vue'),
|
component: () => import('../views/dashboard/HomeworkDetailView.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/stats',
|
path: '/stats',
|
||||||
name: 'stats',
|
name: 'stats',
|
||||||
component: () => import('../views/StatsView.vue'),
|
component: () => import('../views/analytics/StatsView.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/about',
|
path: '/about',
|
||||||
|
@ -47,7 +47,7 @@ const router = createRouter({
|
||||||
// route level code-splitting
|
// route level code-splitting
|
||||||
// this generates a separate chunk (About.[hash].js) for this route
|
// this generates a separate chunk (About.[hash].js) for this route
|
||||||
// which is lazy-loaded when the route is visited.
|
// which is lazy-loaded when the route is visited.
|
||||||
component: () => import('../views/AboutView.vue'),
|
component: () => import('../views/other/AboutView.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
# Views 目录结构
|
||||||
|
|
||||||
|
本项目已将页面按功能分类重新组织,以提高代码的可维护性和可读性。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
src/views/
|
||||||
|
├── auth/ # 认证相关页面
|
||||||
|
│ ├── LoginView.vue # 登录页面
|
||||||
|
│ └── RegisterView.vue # 注册页面
|
||||||
|
│
|
||||||
|
├── dashboard/ # 主要功能页面
|
||||||
|
│ ├── HomeView.vue # 首页
|
||||||
|
│ ├── CoursesView.vue # 课程列表
|
||||||
|
│ ├── CourseDetailView.vue # 课程详情
|
||||||
|
│ ├── HomeworkView.vue # 作业列表
|
||||||
|
│ ├── HomeworkDetailView.vue # 作业详情
|
||||||
|
│ └── ExamView.vue # 考试页面
|
||||||
|
│
|
||||||
|
├── learning/ # 学习管理页面
|
||||||
|
│ ├── PlanView.vue # 学习计划
|
||||||
|
│ ├── ProgressView.vue # 学习进度
|
||||||
|
│ └── ResourcesView.vue # 学习资源
|
||||||
|
│
|
||||||
|
├── social/ # 社交功能页面
|
||||||
|
│ └── ForumView.vue # 论坛页面
|
||||||
|
│
|
||||||
|
├── profile/ # 个人中心页面
|
||||||
|
│ ├── ProfileView.vue # 个人资料
|
||||||
|
│ ├── SettingsView.vue # 设置页面
|
||||||
|
│ └── NotificationsView.vue # 通知页面
|
||||||
|
│
|
||||||
|
├── analytics/ # 数据分析页面
|
||||||
|
│ └── StatsView.vue # 统计页面
|
||||||
|
│
|
||||||
|
└── other/ # 其他页面
|
||||||
|
└── AboutView.vue # 关于页面
|
||||||
|
```
|
||||||
|
|
||||||
|
## 分类说明
|
||||||
|
|
||||||
|
### auth/ - 认证相关
|
||||||
|
包含用户登录、注册等认证功能的页面。
|
||||||
|
|
||||||
|
### dashboard/ - 主要功能
|
||||||
|
包含应用的核心功能页面,如首页、课程管理、作业管理等。
|
||||||
|
|
||||||
|
### learning/ - 学习管理
|
||||||
|
包含学习计划、进度跟踪、资源管理等学习相关的页面。
|
||||||
|
|
||||||
|
### social/ - 社交功能
|
||||||
|
包含论坛、讨论等社交互动功能的页面。
|
||||||
|
|
||||||
|
### profile/ - 个人中心
|
||||||
|
包含用户个人资料、设置、通知等个人相关功能的页面。
|
||||||
|
|
||||||
|
### analytics/ - 数据分析
|
||||||
|
包含统计图表、数据分析等功能的页面。
|
||||||
|
|
||||||
|
### other/ - 其他页面
|
||||||
|
包含关于页面等其他辅助功能的页面。
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 所有路由配置已更新以反映新的文件路径
|
||||||
|
2. 请确保在开发时重新启动开发服务器以清除缓存
|
||||||
|
3. 如果遇到导入错误,请检查文件路径是否正确
|
Loading…
Reference in New Issue