更新样式和功能:添加背景图、打字机效果,优化留言板和吐槽区布局

This commit is contained in:
qingfeng1121
2025-09-29 18:39:10 +08:00
parent ade67e4411
commit aaf326ed1f
8 changed files with 519 additions and 422 deletions

View File

@@ -72,6 +72,7 @@
/* 页面背景设置 */
body {
background-image: url('../img/8.21.1.jpg');
background-size: 120% 120%;
/* 背景图片缩放比例 */
background-repeat: no-repeat;
@@ -179,7 +180,11 @@ p {
display: flex;
border-right: 0;
}
/* 内容通用背景区样式 */
#allstyle {
background-color: rgba(255, 255, 255, 0.85);
border-radius: 10px;
}
/* 内容区样式 */
#content-section {
min-height: 100vh;
@@ -231,6 +236,19 @@ p {
height: var(--hero-height-small);
}
/* 打字机效果 */
.typewriter {
white-space: pre;
min-height: 2.5em;
font-size: var(--title-font-size, 2rem);
}
@keyframes blink {
50% {
border-color: transparent;
}
}
/* hero 主标题样式 */
.hero h1 {
font-size: var(--title-font-size);
@@ -282,6 +300,7 @@ p {
--content-margin: 0;
--leftmodlue-width: 100%;
--nonsense-title-width: 95%;
--nav-padding-small: 0 8px;
}
.elrow-top {

View File

@@ -3,14 +3,12 @@
<el-row justify="center">
<el-col :span="4" v-if="windowwidth">
<div class="grid-content ep-bg-purple-dark">
<!-- <div><img src="../public/favicon.ico" alt=""></div> -->
<div>清疯不颠</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 :default-active="activeIndex" class="el-menu-demo" :collapse="false" @select="handleSelect">
<el-menu-item index="/:type">
首页
</el-menu-item>
@@ -35,7 +33,7 @@
</el-row>
</div>
<div class="hero" :class="{ 'newhero': classhero }" v-if="windowwidth">
<h1>如果感到累了撸一管就好了</h1>
<h1 class="typewriter">{{ heroText }}</h1>
</div>
<div id="content-section" :class="{ 'visible': isconts }">
@@ -54,309 +52,161 @@
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router'
import leftmodlue from '@/views/leftmodlue.vue'
import { ref, onMounted, onUnmounted } from 'vue';
import { useRouter } from 'vue-router';
import leftmodlue from '@/views/leftmodlue.vue';
// hero 的高度更新
// hero 区域样式控制
const classhero = ref(false);
const isconts = ref(false); // 内容
// 内容区可见性
const isconts = ref(false);
// 左侧模块滚动状态
const isScrollingleftmodlue = ref(false);
const elrowtop = ref(); // 导航
const classnonsenset = ref(false) // 疯言疯语
const windowwidth = ref(true) // 屏幕
// 路由
const router = useRouter()
// 导航栏样式类名
const elrowtop = ref('transparent');
// 疯言疯语标题区显示
const classnonsenset = ref(false);
// 屏幕宽度标记true为大屏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 router = useRouter();
/**
* 菜单选择跳转
*/
const handleSelect = (key: string) => {
router.push({
path: key
})
}
// 是否在某页面
const isclass = (url: any) => {
classhero.value = url != '/:type';
classnonsenset.value = url == '/nonsense'
}
router.push({ path: key });
};
// url监听
// 使用router.beforeEach或router.afterEach全局守卫
/**
* 根据路由路径设置页面状态
*/
const updatePageState = (url: string) => {
classhero.value = url !== '/:type';
classnonsenset.value = url === '/nonsense';
};
/**
* 路由切换时处理页面状态和滚动
*/
router.beforeEach((to) => {
// console.log("从", from.path, "到", to.path);
isclass(to.path)
// 回到顶部
window.scrollTo({
top: 0,
behavior: 'smooth' // 平滑滚动
updatePageState(to.path);
setActiveIndex(to.path);
// 跳转后回到顶部
window.scrollTo({ top: 0, behavior: 'smooth' });
// 首页内容区滚动动画仅大屏下生效
if (to.path === '/:type') {
isconts.value = window.innerWidth <= 768 ? true : false;
// 首页时启动打字机
startTypewriter();
} else {
isconts.value = true;
heroText.value = '';
if (heroTimer) clearInterval(heroTimer);
}
});
});
// 滚动事件
/**
* 滚动事件处理
*/
const handleScroll = () => {
const scrollYmo = window.scrollY;
// 只有首页才会执行页面内容滚动效果
if (location.pathname == '/:type') {
// 屏幕小于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 (location.pathname === '/:type') {
isconts.value = window.scrollY > 200;
isScrollingleftmodlue.value = window.scrollY > 600;
} else {
isconts.value = true;
isScrollingleftmodlue.value = true;
}
// 导航
if (scrollYmo > 1200) {
elrowtop.value = 'hide'
} else {
elrowtop.value = window.scrollY > 100 ? 'solid' : 'transparent';
}
};
/**
* 添加滚动监听
*/
const addScrollListener = () => {
window.addEventListener('scroll', handleScroll);
};
/**
* 移除滚动监听
*/
const removeScrollListener = () => {
window.removeEventListener('scroll', handleScroll);
};
const mediaquery = () => {
// 在这里处理屏幕大小变化
/**
* 屏幕尺寸变化处理
* 小屏时移除滚动监听并设置相关状态
* 大屏时添加滚动监听
*/
const handleResize = () => {
if (window.innerWidth < 768) {
removeScrollListener();
windowwidth.value = false
isScrollingleftmodlue.value = true
classnonsenset.value = false
windowwidth.value = false;
isScrollingleftmodlue.value = true;
classnonsenset.value = false;
isconts.value = true;
removeScrollListener();
} else {
windowwidth.value = true;
addScrollListener();
windowwidth.value = true
}
};
// 页面加载完成后执行
const activeIndex = ref('/:type')
const isactiveindex = () => {
// 获取当前路径
const currentPath = window.location.pathname;
// 判断路径并设置hero值
activeIndex.value = currentPath;
}
/**
* 设置当前激活菜单
*/
const setActiveIndex = (locationpathname) => {
activeIndex.value = locationpathname;
};
window.addEventListener('DOMContentLoaded', () => {
isactiveindex();
mediaquery();
// 生命周期钩子
onMounted(() => {
handleResize();
window.addEventListener('resize', handleResize);
// 初始进入时如果是首页,启动打字机
if (window.location.pathname === '/:type') {
startTypewriter();
}
});
window.addEventListener('resize', mediaquery);
window.addEventListener('DOMContentLoaded', isactiveindex);
// 输入框
onUnmounted(() => {
removeScrollListener();
window.removeEventListener('resize', handleResize);
if (heroTimer) clearInterval(heroTimer);
});
</script>
<style></style>
<!-- <style>
body {
/* background-image: url(./img/8.21.1.jpg); */
background-size: 120% 120%;
background-repeat: no-repeat;
background-position: center;
background-attachment: fixed;
}
body ul {
border-bottom: 0px;
}
.h1,
.h2,
.h3,
.h4,
.h5,
.h6,
h1,
h2,
h3,
h4,
h5,
h6 {
font-family: inherit;
font-weight: 400;
line-height: 1.5;
margin-bottom: .5rem;
color: #32325d;
}
p {
font-size: 1rem;
font-weight: 300;
line-height: 1.7;
}
.cont {
margin-top: 5%;
}
/* 导航 */
.elrow-top {
position: fixed;
top: 0;
left: 0;
width: 100%;
padding: 20px 40px;
justify-content: space-between;
align-items: center;
z-index: 1000;
transition: all 0.4s ease;
font-size: inherit;
}
.elrow-top.transparent {
background-color: transparent;
}
.elrow-top.solid {
background-color: rgba(145, 196, 238, 0.85);
padding: 15px 40px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.1);
}
.elrow-top.hide {
background-color: rgba(145, 196, 238, 0);
box-shadow: 0 5px 20px rgba(0, 0, 0, 0);
top: -100px;
transition: all 0.8s ease;
}
.elrow-top .el-row .el-col .grid-content .el-menu--horizontal {
border-bottom: 0px;
}
.el-menu--horizontal {
background: rgb(0, 0, 0, 0);
}
.el-menu-demo {
font-weight: bold;
font-size: 20px;
left: 10%;
}
.el-menu-demo .el-menu-item {
margin-left: 10px;
}
.el-menu.el-menu--horizontal.el-menu-demo .el-menu-item {
font-size: inherit;
}
.el-menu.el-menu--horizontal.el-menu-demo .el-menu-item:hover,
.el-menu.el-menu--horizontal.el-menu-demo .el-menu-item.is-active {
background-color: rgb(0, 0, 0, 0);
}
/* 内容 */
#content-section {
min-height: 100vh;
padding: 100px 10%;
opacity: 0;
transform: translateY(50px);
transition: all 0.8s ease-out;
/* margin: 20px 0; */
border-radius: 10px;
display: flex;
}
#content-section.visible {
opacity: 1;
transform: translateY(0);
}
.search {
margin-top: 12px;
}
.grid-content {
text-align: center;
}
.RouterViewpage {
width: 80%;
margin-left: 5%;
margin-right: 5%;
}
/* 分页 */
.Pagination {
align-self: center;
background-color: aqua;
}
#search {
display: flex;
}
.el-button {
background-color: rgb(0, 0, 0, 0);
border: 0px;
}
/* 状态栏 */
.leftmodluepage {
width: 20%;
}
/* 开头标题样式*/
.hero {
height: 600px;
margin-top: 5%;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
color: white;
}
.hero.newhero {
height: 200px;
transition: all 0.3s ease;
}
.hero h1 {
font-size: 3.5rem;
margin-bottom: 20px;
}
.hero p {
font-size: 1.5rem;
max-width: 700px;
margin: 0 auto 30px;
}
/* 疯言疯语标题 */
.nonsensetitle {
text-align: center;
position: absolute;
top: 0;
width: 76.5%;
padding: 20px;
margin-bottom: 50px;
background: rgba(255, 255, 255, 0.1) !important;
backdrop-filter: blur(10px);
border-radius: 20px;
}
.nonsensetitle .nonsensetitleconst {
padding: 1.5rem;
flex: 1 1 auto;
box-sizing: border-box;
}
.nonsensetitle .nonsensetitleconst p {
font-size: 1rem;
}
/* 调整样式 */
.nonsensetmargintop {
margin-top: 130px;
}
/* 输入框 */
</style> -->
<style>
</style>

View File

@@ -2,7 +2,6 @@ import { createApp } from 'vue'
import App from './App.vue'
import Router from './router/Router'
import './assets/index.css'
const app = createApp(App)
app.use(Router)
app.mount('#app')

View File

@@ -89,11 +89,6 @@ const datas = [
]
</script>
<style>
#allstyle {
background-color: rgba(255, 255, 255, 0.85);
border-radius: 10px;
}
.header {
text-align: center;
padding: 20px;

View File

@@ -1,18 +1,16 @@
<!-- 文章模板 -->
<template>
<div>
<div class="button-example" @click="aericleClick(items.aur) " v-for="items in datas">
<div v-if="items.mg == ''">
<h2>{{ items.title }}</h2>
<el-text class="mx-1">{{ items.author }}</el-text>
<p>{{ items.publishedAt }}</p>
</div>
<div v-else="items.mg != ''">
<h2>{{ items.title }}</h2>
<el-text class="mx-1">{{ items.author }}</el-text>
<div>mg</div>
<p>{{ items.publishedAt }}</p>
</div>
<div
class="article-card"
v-for="item in datas"
:key="item.title + item.publishedAt"
@click="aericleClick(item.aur)"
>
<h2>{{ item.title }}</h2>
<el-text class="mx-1">{{ item.author }}</el-text>
<div v-if="item.mg">mg</div>
<p>{{ item.publishedAt }}</p>
</div>
</div>
</template>
@@ -20,14 +18,16 @@
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
// 跳转到文章详情
const aericleClick = (aur) => {
router.push({
path: '/articlecontents/:url',
query:{
url:aur
}
query: { url: aur }
})
}
// 文章数据
const datas = [
{
title: '测试1',
@@ -115,10 +115,19 @@ const datas = [
mg_b: '',
publishedAt: '2016-04-12'
},
{
title: '测试2',
author: '这是img模块测试',
aur: '链接',
mg: '',
mg_b: '',
publishedAt: '2016-04-12'
},
]
</script>
<style scoped>
.button-example {
.article-card {
border-radius: 10px;
display: flex;
flex-direction: column;
@@ -126,15 +135,12 @@ const datas = [
background-color: rgba(255, 255, 255, 0.85);
padding: 15px;
margin-bottom: 30px;
}
.button-example {
transition: all 0.4s ease;
position: relative;
overflow: hidden;
cursor: pointer;
}
.button-example::before {
.article-card::before {
content: '';
position: absolute;
top: 0;
@@ -149,14 +155,12 @@ const datas = [
opacity: 0;
transition: opacity 0.4s ease;
}
.button-example:hover {
.article-card:hover {
transform: translateY(-5px) perspective(2000px) rotateX(0);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.25),
0 0 50px rgba(255, 255, 255, 0.3);
}
.button-example:hover::before {
.article-card:hover::before {
opacity: 1;
}
</style>

View File

@@ -14,7 +14,7 @@
<p>左眼右右眼左四十五度成就美</p>
</div>
<div class="cont2">
<el-menu class="el-menu-vertical-demo" @select="handleSelect">
<el-menu :default-active="activeIndex" class="el-menu-vertical-demo" @select="handleSelect">
<el-menu-item index="/:type">
<el-icon>
</el-icon>
@@ -52,127 +52,158 @@
import { reactive, ref, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
// 当前激活菜单
const activeIndex = ref('/:type')
const router = useRouter()
const activeName = ref('first')
const state = reactive({
circleUrl:
'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
squareUrl:
'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
circleUrl: 'https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
squareUrl: 'https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png',
sizeList: ['small', '', 'large'] as const,
})
const handleSelect = (key: string, keyPath: string[]) => {
router.push({
path: key
})
// 处理菜单选择跳转
const handleSelect = (key: string) => {
router.push({ path: key })
}
// 滚动事件
const scrollY = ref(false);
const handleScroll = () => {
const scrollYmo = window.scrollY;
scrollY.value = scrollYmo > 1100;
};
window.addEventListener('scroll', handleScroll);
// 路由切换时同步菜单高亮
router.beforeEach((to) => {
activeIndex.value = to.path
})
// 控制底部模块吸顶效果
const scrollY = ref(false)
const handleScroll = () => {
scrollY.value = window.scrollY > 1100
}
// 生命周期管理事件监听,防止内存泄漏
onMounted(() => {
window.addEventListener('scroll', handleScroll)
})
onUnmounted(() => {
window.removeEventListener('scroll', handleScroll)
})
</script>
<style>
/* 整体布局外层每个子div底部间距 */
#alld div {
margin-bottom: 15px;
}
/* 顶部公告栏样式 */
#top {
height: 100px;
border-radius: 10px;
background-color: rgb(102, 161, 216, 0.9);
background-color: rgba(102, 161, 216, 0.9); /* 蓝色半透明背景 */
text-align: left;
padding: 15px;
}
/* 公告栏副标题字体大小 */
#top .top2 p {
font-size: 15px;
}
/* 中部内容区整体样式 */
#cont {
padding: 15px;
height: 350px;
border-radius: 10px;
padding: 0;
}
/* */
/* 内容区上半部分(标题) */
#cont .cont1 {
border-radius: 10px 10px 0 0;
padding: 15px;
text-align: center;
margin-bottom: 0;
background-color: rgb(102, 161, 216, 0.9);
background-color: rgba(102, 161, 216, 0.9); /* 蓝色半透明背景 */
}
/* 内容区下半部分(菜单) */
#cont .cont2 {
padding: 10px 0;
border-radius: 0 0 10px 10px;
background-color: rgba(215, 224, 218, 0.9);
background-color: rgba(215, 224, 218, 0.9); /* 浅绿色半透明背景 */
}
/* 菜单整体样式 */
#cont .cont2 .el-menu-vertical-demo {
display: inline;
}
/* 菜单项悬停效果 */
#cont .cont2 .el-menu-vertical-demo .el-menu-item:hover {
background-color: rgb(255, 255, 255 , 0.7);
}
.el-menu-vertical-demo {
background-color: rgb(0, 0, 0, 0);
border-right: 0px;
background-color: rgba(255, 255, 255, 0.7); /* 白色半透明 */
}
/* 菜单背景透明,去除右边框 */
.el-menu-vertical-demo {
background-color: transparent;
border-right: 0;
}
/* 去除内容区和底部区子div的底部间距 */
#cont div,
#bot div {
margin-bottom: 0%;
margin-bottom: 0;
}
/* */
/* 底部模块样式 */
#bot {
padding: 15px;
border-radius: 10px;
background-color: rgb(0, 233, 70, 0.7);
background-color: rgba(0, 233, 70, 0.7); /* 绿色半透明背景 */
transition: all 0.4s ease;
}
/* 底部模块吸顶效果 */
#bot.botrelative {
transition: all 0.4s ease;
position: sticky;
top: 20px;
}
/* tabs整体居中字体颜色 */
.demo-tabs {
text-align: center;
color: #6b778c;
}
/* tabs导航栏高度和下边距 */
.el-tabs__nav-scroll {
height: 45px;
margin-bottom: 5px;
}
/* tabs导航栏宽度 */
.el-tabs__nav {
width: 100%;
}
/* tabs每个item宽度一半 */
.el-tabs__item {
width: 50%;
}
/* 去除tabs导航栏底部线 */
.el-tabs__nav-wrap:after {
height: 0px;
height: 0;
}
/* 头像容器,垂直水平居中 */
.mylogo {
height: 80px;
display: flex;
justify-content: center;
align-items: center;
}
/* 头像悬停放大效果 */
.el-avatar:hover {
transform: scale(2);
z-index: 2;

View File

@@ -1,29 +1,36 @@
<template>
<div id="messahe_all">
<div id="allstyle">
<div class="header">
<div id="message_all">
<!-- 标题区 -->
<div class="message-header">
<h1>留言板</h1>
</div>
<!-- 留言内容区 -->
<div class="message-list">
<div class="message-item" v-for="msg in messages" :key="msg.id">
<div class="message-nickname">{{ msg.nickname }}</div>
<div class="message-content">{{ msg.content }}</div>
<div class="message-time">{{ msg.time }}</div>
</div>
<div id="allstyle" class="botom">
<h1>发送评论(请正确填写邮箱地址否则将会当成垃圾评论处理)</h1>
<el-form :model="form">
<!-- 输入框 -->
<div v-if="messages.length === 0" class="message-empty">还没有留言快来抢沙发吧</div>
</div>
<!-- 留言输入区 -->
<div class="message-form-section">
<h2>发送评论请正确填写邮箱地址否则将会当成垃圾评论处理</h2>
<el-form :model="form" label-width="0">
<el-form-item>
<el-input v-model="form" placeholder="评论内容" type="textarea" />
<el-input v-model="form.content" placeholder="评论内容" type="textarea" rows="4" clearable />
</el-form-item>
<div class="botom_form_input">
<div class="form-input-row">
<el-form-item>
<el-input v-model="form" placeholder="昵称" clearable />
<el-input v-model="form.nickname" placeholder="昵称" clearable />
</el-form-item>
<el-form-item>
<el-input v-model="form" placeholder="邮箱/QQ号" clearable />
<el-input v-model="form.email" placeholder="邮箱/QQ号" clearable />
</el-form-item>
<el-form-item>
<el-input v-model="form" placeholder="验证码" clearable />
<el-input v-model="form.captcha" placeholder="验证码" clearable />
</el-form-item>
</div>
<!-- 按钮 -->
<el-form-item>
<el-button type="primary" @click="onSubmit">发送</el-button>
</el-form-item>
@@ -31,43 +38,128 @@
</div>
</div>
</template>
<script>
import { reactive } from 'vue'
// do not use same name with ref
<script setup>
import { reactive, ref } from 'vue'
const messages = ref([
{ id: 1, nickname: 'A', content: '这里是A', time: '2025-09-26 10:00' },
{ id: 2, nickname: 'B', content: '这里是B', time: '2025-09-26 10:05' },
{ id: 3, nickname: 'C', content: '这里是C', time: '2025-09-26 10:10' }
])
const form = reactive({
name: '',
region: '',
type: [],
resource: '',
desc: '',
content: '',
nickname: '',
email: '',
captcha: ''
})
const onSubmit = () => {
console.log('submit!')
if (!form.content || !form.nickname) return
messages.value.push({
id: messages.value.length + 1,
nickname: form.nickname,
content: form.content,
time: new Date().toLocaleString()
})
}
</script>
<style>
.botom{
padding: 20px;
<style scoped>
#message_all {
width: var(--content-width);
margin: var(--content-margin);
}
#allstyle.botom{
margin-top: 10px;
.message-header {
background: rgba(102, 161, 216, 0.9);
border-radius: 12px;
padding: 20px 0;
text-align: center;
margin-bottom: 20px;
}
.botom_form_input{
.message-list {
margin-bottom: 24px;
background: #f8fafd;
border-radius: 12px;
padding: 16px;
min-height: 120px;
}
.message-item {
background: #fff;
border-radius: 10px;
padding: 14px 18px;
margin-bottom: 12px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.03);
}
.message-nickname {
font-weight: bold;
color: #409eff;
margin-bottom: 4px;
}
.message-content {
margin-bottom: 4px;
color: #333;
}
.message-time {
font-size: 12px;
color: #aaa;
text-align: right;
}
.message-empty {
color: #bbb;
text-align: center;
padding: 32px 0;
}
.message-form-section {
background: #fff;
border-radius: 12px;
padding: 24px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.message-form-section h2 {
font-size: 1.1rem;
margin-bottom: 18px;
color: #333;
}
.form-input-row {
display: flex;
gap: 16px;
margin-bottom: 12px;
}
.botom_form_input .el-form-item{
width: 30%;
display: block;
.form-input-row .el-form-item {
flex: 1;
}
.botom_form_input .el-form-item:nth-child(2){
margin: 0 2.5%;
.el-form-item .el-input__inner,
.el-form-item .el-textarea__inner {
min-height: 45px;
font-size: 1rem;
}
@media (max-width: 768px) {
#message_all {
padding: 8px 0;
}
.message-form-section {
padding: 12px;
}
.form-input-row {
flex-direction: column;
gap: 8px;
}
.botom_form_input .el-form-item .el-input__inner {
height: 45px;
}
</style>

View File

@@ -1,7 +1,114 @@
<template>
<div id="allstyle">
<div class="header">
<h1>疯言疯语</h1>
<div id="aericle-style">
<div class="aericle-list">
<div
class="aericle-item"
v-for="item in aericleList"
:key="item.id"
>
<div class="aericle-meta">
<span class="aericle-time">{{ item.time }}</span>
</div>
<div class="aericle-content">{{ item.content }}</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
// 吐槽数据(仅站长可见/可发)
const aericleList = ref([
{
id: 1,
content: '今天写代码写到怀疑人生bug像是无穷无尽的海洋……',
time: '2025-09-26 09:30'
},
{
id: 2,
content: '前端样式调到崩溃,为什么不同浏览器都不一样!',
time: '2025-09-26 10:12'
},
{
id: 3,
content: 'AI 说得都对,但我还是想摸鱼。',
time: '2025-09-26 11:00'
},
{
id: 4,
content: '有时候觉得自己像个 bug 生产机。',
time: '2025-09-26 13:14'
}
])
</script>
<style scoped>
#aericle-style {
background: rgba(255,255,255,0.95);
border-radius: 12px;
padding: 32px 20px 24px 20px;
box-shadow: 0 2px 12px rgba(0,0,0,0.06);
}
.aericle-header {
text-align: center;
margin-bottom: 28px;
}
.aericle-header h1 {
font-size: 2.2rem;
margin-bottom: 8px;
color: #409eff;
letter-spacing: 2px;
}
.aericle-desc {
color: #888;
font-size: 1rem;
margin-bottom: 0;
}
.aericle-list {
display: flex;
flex-direction: column;
gap: 18px;
}
.aericle-item {
background: #f8fafd;
border-radius: 10px;
padding: 18px 20px 14px 20px;
box-shadow: 0 1px 4px rgba(0,0,0,0.03);
position: relative;
transition: box-shadow 0.2s;
}
.aericle-item:hover {
box-shadow: 0 4px 16px rgba(64,158,255,0.12);
}
.aericle-meta {
font-size: 13px;
color: #aaa;
margin-bottom: 8px;
text-align: right;
}
.aericle-content {
font-size: 1.08rem;
color: #333;
line-height: 1.8;
word-break: break-all;
}
@media (max-width: 768px) {
#aericle-style {
padding: 14px 4px 10px 4px;
margin: 10px 0 0 0;
}
.aericle-header h1 {
font-size: 1.4rem;
}
.aericle-content {
font-size: 0.98rem;
}
}
</style>