Files
MyfronyProject/src/layouts/MainLayout.vue
qingfeng1121 b8362e7835 feat: 重构前端项目结构并添加新功能
重构项目目录结构,将组件和服务模块化
添加Element Plus UI库并集成到项目中
实现文章、留言和分类的类型定义
新增工具函数模块包括日期格式化和字符串处理
重写路由配置并添加全局路由守卫
优化页面布局和响应式设计
新增服务层封装API请求
完善文章详情页和相关文章推荐功能
2025-10-12 14:24:20 +08:00

206 lines
5.2 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.

<template>
<div class="elrow-top" :class="elrowtop">
<el-row justify="center">
<el-col :span="4" v-if="windowwidth">
<div class="grid-content ep-bg-purple-dark">
<div class="logo-text">清疯不颠</div>
</div>
</el-col>
<el-col :span="14" justify="center">
<div class="grid-content ep-bg-purple-dark">
<el-menu :default-active="activeIndex" class="el-menu-demo" :collapse="false" @select="handleSelect">
<el-menu-item index="/:type">
首页
</el-menu-item>
<el-menu-item index="/article-list">
目录
</el-menu-item>
<el-menu-item index="/nonsense">
疯言疯语
</el-menu-item>
<el-menu-item index="/about">
关于
</el-menu-item>
<el-menu-item index="/message">
留言板
</el-menu-item>
</el-menu>
</div>
</el-col>
<el-col :span="2" class="search-container" v-if="windowwidth">
<!-- 搜索框可以在这里添加 -->
</el-col>
</el-row>
</div>
<!-- Hero 区域 -->
<div class="hero" :class="{ 'newhero': classhero }" v-if="windowwidth">
<h1 class="typewriter">{{ heroText }}</h1>
</div>
<!-- 主内容区域 -->
<div id="content-section" :class="{ 'visible': isconts }">
<div class="nonsensetitle" v-if="classnonsenset">
<div class="nonsensetitleconst">
<h1>发癫中QAQ</h1>
</div>
</div>
<!-- 左侧模块 -->
<LeftModule class="leftmodluepage" :class="{ 'nonsensetmargintop': classnonsenset }" v-if="windowwidth" />
<!-- 内容模块 -->
<RouterView class="RouterViewpage" :class="{ 'nonsensetmargintop': classnonsenset }" />
</div>
<!-- 分页区域 -->
<div class="Pagination">
<!-- 分页组件可以在这里添加 -->
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import LeftModule from '@/components/LeftModule.vue';
// 路由相关
const router = useRouter();
const route = useRoute();
// 响应式状态
const classhero = ref(false);
const isconts = ref(false);
const isScrollingleftmodlue = ref(false);
const elrowtop = ref('transparent');
const classnonsenset = ref(false);
const windowwidth = ref(true);
const activeIndex = ref('/:type');
// 打字机效果相关
const fullHeroText = '如果感到累了撸一管就好了';
const heroText = ref('');
let heroIndex = 0;
let heroTimer: number | undefined;
/**
* 打字机效果函数
*/
const startTypewriter = () => {
heroText.value = '';
heroIndex = 0;
if (heroTimer) clearInterval(heroTimer);
heroTimer = window.setInterval(() => {
if (heroIndex < fullHeroText.length) {
heroText.value += fullHeroText[heroIndex];
heroIndex++;
} else {
clearInterval(heroTimer);
}
}, 100);
};
/**
* 菜单选择跳转
*/
const handleSelect = (key: string) => {
router.push({ path: key });
};
/**
* 根据路由路径设置页面状态
*/
const updatePageState = (url: string) => {
classhero.value = url !== '/:type';
classnonsenset.value = url === '/nonsense';
};
/**
* 设置当前激活的菜单项
*/
const setActiveIndex = (path: string) => {
activeIndex.value = path;
};
/**
* 处理窗口大小变化
*/
const handleResize = () => {
windowwidth.value = window.innerWidth > 768;
// 根据屏幕大小调整内容区可见性
if (route.path === '/:type') {
isconts.value = window.innerWidth <= 768 ? true : false;
}
};
/**
* 处理滚动事件
*/
const handleScroll = () => {
// 屏幕小于768时只切换导航栏样式不做内容动画
if (window.innerWidth < 768) {
elrowtop.value = window.scrollY > 100 ? 'solid' : 'transparent';
return;
}
// 导航栏样式切换
if (window.scrollY > 1200) {
elrowtop.value = 'hide';
} else {
elrowtop.value = window.scrollY > 100 ? 'solid' : 'transparent';
}
// 首页内容区滚动动画
if (route.path === '/:type') {
isconts.value = window.scrollY > 200;
isScrollingleftmodlue.value = window.scrollY > 600;
}
};
/**
* 监听路由变化
*/
watch(() => route.path, (newPath) => {
updatePageState(newPath);
setActiveIndex(newPath);
// 跳转后回到顶部
window.scrollTo({ top: 0, behavior: 'smooth' });
// 首页内容区滚动动画仅大屏下生效
if (newPath === '/:type') {
isconts.value = window.innerWidth <= 768 ? true : false;
// 首页时启动打字机
startTypewriter();
} else {
isconts.value = true;
heroText.value = '';
if (heroTimer) clearInterval(heroTimer);
}
}, { immediate: true });
/**
* 生命周期钩子
*/
onMounted(() => {
// 初始化窗口大小
handleResize();
// 添加事件监听器
window.addEventListener('resize', handleResize);
window.addEventListener('scroll', handleScroll);
});
onUnmounted(() => {
// 清理事件监听器
window.removeEventListener('resize', handleResize);
window.removeEventListener('scroll', handleScroll);
// 清理定时器
if (heroTimer) clearInterval(heroTimer);
});
</script>
<style scoped>
</style>