需要实现的效果如下:
- 左侧分类导航栏:点击左侧分类时,页面会滚动到对应的分类区域,同时更新选中状态(高亮)。
- 右侧内容区:显示每个分类的具体子类别,右侧内容根据滚动位置动态更新左侧导航的选中状态。
- 路由更新:地址栏的
query
参数随导航栏选中状态动态更新(如?group=image
)。
实现步骤
1. HTML 结构
<template>
<div class="container">
<!-- 左侧导航栏 -->
<nav class="sidebar">
<ul>
<li
v-for="category in categories"
:key="category.id"
:class="{ active: currentCategory === category.id }"
@click="scrollToSection(category.id)"
>
{{ category.name }}
</li>
</ul>
</nav>
<!-- 右侧内容区 -->
<main class="content">
<section
v-for="category in categories"
:key="category.id"
:id="'section-' + category.id"
class="category-section"
>
<h2>{{ category.name }}</h2>
<ul>
<li v-for="item in category.items" :key="item.id">
{{ item.name }}
</li>
</ul>
</section>
</main>
</div>
</template>
2. Vue 脚本逻辑
<script>
import { ref, onMounted, onUnmounted } from "vue";
import { useRouter } from "vue-router";
export default {
setup() {
const categories = ref([
{ id: "image", name: "Image", items: ["Text to Image", "AI Avatar Generator"] },
{ id: "video", name: "Video", items: ["AI Animation", "Image to Video"] },
// 添加更多分类
]);
const currentCategory = ref(""); // 当前高亮分类
const router = useRouter();
// 滚动到指定分类
const scrollToSection = (id) => {
const target = document.getElementById(`section-${id}`);
if (target) {
target.scrollIntoView({ behavior: "smooth", block: "start" });
currentCategory.value = id;
router.push({ query: { group: id } }); // 更新路由
}
};
// 滚动监听
const handleScroll = () => {
const sections = document.querySelectorAll(".category-section");
let found = false;
const offset = 100; // 偏移值,适应固定头部
sections.forEach((section) => {
const rect = section.getBoundingClientRect();
if (!found && rect.top <= offset && rect.bottom > offset) {
const id = section.id.replace("section-", "");
if (currentCategory.value !== id) {
currentCategory.value = id;
router.replace({ query: { group: id } }); // 动态更新路由
}
found = true;
}
});
};
onMounted(() => {
window.addEventListener("scroll", handleScroll);
});
onUnmounted(() => {
window.removeEventListener("scroll", handleScroll);
});
return {
categories,
currentCategory,
scrollToSection,
};
},
};
</script>
3. 样式设计
<style scoped>
.container {
display: flex;
}
.sidebar {
width: 200px;
position: sticky;
top: 0;
background: #f8f8f8;
padding: 20px;
}
.sidebar ul {
list-style: none;
padding: 0;
}
.sidebar li {
cursor: pointer;
padding: 10px;
margin-bottom: 5px;
border-radius: 5px;
transition: background 0.3s;
}
.sidebar li.active {
background: #d0e2ff;
color: #000;
}
.sidebar li:hover {
background: #e6f0ff;
}
.content {
flex: 1;
padding: 20px;
}
.category-section {
margin-bottom: 50px;
}
.category-section h2 {
margin-bottom: 20px;
font-size: 24px;
}
</style>
4. 特性解释
-
滚动监听更新路由:
handleScroll
函数监听滚动事件,根据当前滚动位置动态更新currentCategory
和路由。
-
平滑滚动:
- 使用
scrollIntoView
实现点击导航后平滑滚动到对应区域。
- 使用
-
高亮显示:
- 左侧导航栏通过
currentCategory
的值动态添加active
样式。
- 左侧导航栏通过
-
路由支持:
- 使用 Vue Router 的
push
和replace
方法,在点击或滚动时更新地址栏中的query
参数。
- 使用 Vue Router 的
评论(0)