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

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

@@ -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
}
})
router.push({
path: '/articlecontents/:url',
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,37 +135,32 @@ const datas = [
background-color: rgba(255, 255, 255, 0.85);
padding: 15px;
margin-bottom: 30px;
transition: all 0.4s ease;
position: relative;
overflow: hidden;
cursor: pointer;
}
.button-example {
transition: all 0.4s ease;
position: relative;
overflow: hidden;
.article-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg,
rgba(255,255,255,0.6) 0%,
rgba(255,255,255,0.2) 50%,
rgba(255,255,255,0.05) 100%);
pointer-events: none;
opacity: 0;
transition: opacity 0.4s ease;
}
.button-example::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg,
rgba(255,255,255,0.6) 0%,
rgba(255,255,255,0.2) 50%,
rgba(255,255,255,0.05) 100%);
pointer-events: none;
opacity: 0;
transition: opacity 0.4s ease;
.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 {
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 {
opacity: 1;
.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;
border-radius: 10px 10px 0 0;
padding: 15px;
text-align: center;
margin-bottom: 0;
background-color: rgb(102, 161, 216, 0.9);
}
#cont .cont2{
padding: 10px 0;
border-radius:0 0 10px 10px;
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(102, 161, 216, 0.9); /* 蓝色半透明背景 */
}
/* 内容区下半部分(菜单) */
#cont .cont2 {
padding: 10px 0;
border-radius: 0 0 10px 10px;
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: 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">
<h1>留言板</h1>
</div>
<div id="message_all">
<!-- 标题区 -->
<div class="message-header">
<h1>留言板</h1>
</div>
<div id="allstyle" class="botom">
<h1>发送评论(请正确填写邮箱地址否则将会当成垃圾评论处理)</h1>
<el-form :model="form">
<!-- 输入框 -->
<el-form-item >
<el-input v-model="form" placeholder="评论内容" type="textarea" />
<!-- 留言内容区 -->
<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 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.content" placeholder="评论内容" type="textarea" rows="4" clearable />
</el-form-item>
<div class="botom_form_input">
<el-form-item >
<el-input v-model="form" placeholder="昵称" clearable />
<div class="form-input-row">
<el-form-item>
<el-input v-model="form.nickname" placeholder="昵称" clearable />
</el-form-item>
<el-form-item >
<el-input v-model="form" placeholder="邮箱/QQ号" clearable />
<el-form-item>
<el-input v-model="form.email" placeholder="邮箱/QQ号" clearable />
</el-form-item>
<el-form-item >
<el-input v-model="form" placeholder="验证码" clearable />
<el-form-item>
<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;
}
.botom_form_input .el-form-item .el-input__inner {
height: 45px;
@media (max-width: 768px) {
#message_all {
padding: 8px 0;
}
.message-form-section {
padding: 12px;
}
.form-input-row {
flex-direction: column;
gap: 8px;
}
}
</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>