feat: 实现文章搜索功能并优化留言系统
- 添加文章标题搜索功能,支持通过路由参数搜索 - 重构留言板组件,优化留言嵌套结构和交互 - 新增评论演示页面展示嵌套留言功能 - 调整主布局样式和导航菜单路由 - 修复留言板样式问题和数据字段不一致问题
This commit is contained in:
@@ -9,7 +9,7 @@
|
||||
<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 index="/home">
|
||||
首页
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/article-list">
|
||||
@@ -28,7 +28,21 @@
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="2" class="search-container" v-if="windowwidth">
|
||||
<!-- 搜索框可以在这里添加 -->
|
||||
<!-- 搜索功能 -->
|
||||
<div class="search-wrapper">
|
||||
<button class="search-icon-btn" @click="toggleSearchBox" :class="{ 'active': isSearchBoxOpen }">
|
||||
<i class="el-icon-search">1</i>
|
||||
</button>
|
||||
<div class="search-box-container" :class="{ 'open': isSearchBoxOpen }">
|
||||
<el-input
|
||||
v-model="searchKeyword"
|
||||
placeholder="搜索文章..."
|
||||
class="search-input"
|
||||
@keyup.enter="performSearch"
|
||||
@blur="closeSearchBoxWithDelay"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@@ -75,7 +89,14 @@ const isScrollingleftmodlue = ref(false);
|
||||
const elrowtop = ref('transparent');
|
||||
const classnonsenset = ref(false);
|
||||
const windowwidth = ref(true);
|
||||
const activeIndex = ref('/:type');
|
||||
const activeIndex = ref('/home');
|
||||
const localhome= '/home';
|
||||
|
||||
|
||||
// 搜索相关状态
|
||||
const isSearchBoxOpen = ref(false);
|
||||
const searchKeyword = ref('');
|
||||
let searchCloseTimer: number | undefined;
|
||||
|
||||
// 打字机效果相关
|
||||
const fullHeroText = '测试打字机效果';
|
||||
@@ -107,11 +128,59 @@ const handleSelect = (key: string) => {
|
||||
router.push({ path: key });
|
||||
};
|
||||
|
||||
/**
|
||||
* 切换搜索框显示/隐藏
|
||||
*/
|
||||
const toggleSearchBox = () => {
|
||||
isSearchBoxOpen.value = !isSearchBoxOpen.value;
|
||||
|
||||
// 如果打开搜索框,清除之前的延时关闭定时器
|
||||
if (isSearchBoxOpen.value && searchCloseTimer) {
|
||||
clearTimeout(searchCloseTimer);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 关闭搜索框
|
||||
*/
|
||||
const closeSearchBox = () => {
|
||||
isSearchBoxOpen.value = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* 带延迟关闭搜索框(处理点击搜索按钮后的情况)
|
||||
*/
|
||||
const closeSearchBoxWithDelay = () => {
|
||||
if (searchCloseTimer) {
|
||||
clearTimeout(searchCloseTimer);
|
||||
}
|
||||
|
||||
searchCloseTimer = window.setTimeout(() => {
|
||||
isSearchBoxOpen.value = false;
|
||||
}, 300);
|
||||
};
|
||||
|
||||
/**
|
||||
* 执行搜索操作
|
||||
*/
|
||||
const performSearch = () => {
|
||||
if (searchKeyword.value.trim()) {
|
||||
// 这里可以根据实际需求实现搜索逻辑
|
||||
console.log('搜索关键词:', searchKeyword.value);
|
||||
router.push({ path: `/home/aericletitle/${searchKeyword.value}`});
|
||||
}
|
||||
|
||||
// 搜索后保持搜索框打开状态
|
||||
if (searchCloseTimer) {
|
||||
clearTimeout(searchCloseTimer);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据路由路径设置页面状态
|
||||
*/
|
||||
const updatePageState = (url: string) => {
|
||||
classhero.value = url !== '/:type';
|
||||
classhero.value = url !== localhome;
|
||||
classnonsenset.value = url === '/nonsense';
|
||||
};
|
||||
|
||||
@@ -129,7 +198,7 @@ const handleResize = () => {
|
||||
windowwidth.value = window.innerWidth > 768;
|
||||
|
||||
// 根据屏幕大小调整内容区可见性
|
||||
if (route.path === '/:type') {
|
||||
if (route.path === localhome) {
|
||||
isconts.value = window.innerWidth <= 768 ? true : false;
|
||||
}
|
||||
};
|
||||
@@ -152,7 +221,7 @@ const handleScroll = () => {
|
||||
}
|
||||
|
||||
// 首页内容区滚动动画
|
||||
if (route.path === '/:type') {
|
||||
if (route.path === localhome) {
|
||||
isconts.value = window.scrollY > 200;
|
||||
isScrollingleftmodlue.value = window.scrollY > 600;
|
||||
}
|
||||
@@ -169,13 +238,13 @@ watch(() => route.path, (newPath) => {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
|
||||
// 首页内容区滚动动画仅大屏下生效
|
||||
if (newPath === '/:type') {
|
||||
if (newPath === localhome) {
|
||||
isconts.value = window.innerWidth <= 768 ? true : false;
|
||||
// 首页时启动打字机
|
||||
startTypewriter();
|
||||
} else {
|
||||
isconts.value = true;
|
||||
heroText.value = '';
|
||||
heroText.value =fullHeroText;
|
||||
if (heroTimer) clearInterval(heroTimer);
|
||||
}
|
||||
}, { immediate: true });
|
||||
@@ -185,6 +254,8 @@ watch(() => route.path, (newPath) => {
|
||||
*/
|
||||
onMounted(() => {
|
||||
// 初始化窗口大小
|
||||
|
||||
|
||||
handleResize();
|
||||
|
||||
// 添加事件监听器
|
||||
@@ -203,4 +274,80 @@ onUnmounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 搜索框样式 */
|
||||
.search-wrapper {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.search-icon-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
/* padding: 8px; */
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.search-icon-btn:hover,
|
||||
.search-icon-btn.active {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.search-box-container {
|
||||
position: absolute;
|
||||
right: 100%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
/* box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1); */
|
||||
overflow: hidden;
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
transition: all 0.3s ease;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.search-box-container.open {
|
||||
width: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
border: none;
|
||||
outline: none;
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
/* padding: 0 8px; */
|
||||
border: none;
|
||||
}
|
||||
|
||||
.search-btn,
|
||||
.close-btn {
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
color: #606266;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.search-btn:hover,
|
||||
.close-btn:hover {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
/* 防止搜索框在小屏幕上重叠 */
|
||||
@media screen and (max-width: 1200px) {
|
||||
.search-box-container.open {
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user