home页面
<template>
<Container>
// 右侧区域的每一个内容区域
<ProductF id="proRef0" ref="proRef0" />
<ProductT id="proRef1" ref="proRef1" />
<ProductH id="proRef2" ref="proRef2" />
<ProductA id="proRef3" ref="proRef3" />
<ProductQ id="proRef4" ref="proRef4" />
</Container>
</template>
<script>
import Container from '@/components/Container/index.vue'
import ProductF from './Product/Product1/index.vue'
import ProductT from './Product/Product2/index.vue'
import ProductH from './Product/Product3/index.vue'
import ProductA from './Product/Product4/index.vue'
import ProductQ from './Product/Product5/index.vue'
export default {
components: { Container, ProductF, ProductT, ProductH, ProductA, ProductQ }
}
</script>
<style>
</style>
Container页面
<template>
<div ref="mainsECTION" class="main-section" @scroll="handleScroll">
<slot ref="aa" />
</div>
</template>
<script>
export default {
mounted() {
window.addEventListener('scroll', this.handleScroll, true)
},
methods: {
// 右侧区域滚动事件
handleScroll(e) {
this.$eventBus.$emit('handleScroll', e)
}
}
}
</script>
<style lang="scss" scoped>
.main-section{
padding: 20px;
// width: 100%;
flex: 1;
height: 100%;
overflow-y: auto;
}
</style>
主页面
<template>
<div class="content">
// 左侧菜单栏
<div class="left-menu">
<ul id="uu">
<li v-for="item,index in leftMenu" :key="index" :class="{active: activeClick === index}" @click="changeHash(item.ids,index)" @mouseover="mouseover(index)" @mouseout="mouseout">
<img :src="activeIndex === index ||activeClick === index? imgData[index].src1 : imgData[index].src2" alt="">
{{ item.name }}
</li>
</ul>
</div>
// 右侧内容区域
<div style="flex:1">
// 内容区域
<home ref="home" />
</div>
</div>
</template>
<script>
import home from '../../../views/index.vue'
import { mapGetters } from 'vuex'
export default {
name: 'LeftNav',
components: { home },
data() {
return {
// 菜单栏左边的图标
imgData: [
{
src1: require('../../../assets/img/高亮1.png'),
src2: require('../../../assets/img/灰1.png')
},
{
src1: require('../../../assets/img/高亮2.png'),
src2: require('../../../assets/img/灰2.png')
},
{
src1: require('../../../assets/img/高亮3.png'),
src2: require('../../../assets/img/灰3.png')
},
{
src1: require('../../../assets/img/高亮4.png'),
src2: require('../../../assets/img/灰4.png')
},
{
src1: require('../../../assets/img/高亮5.png'),
src2: require('../../../assets/img/灰5.png')
}
],
activeIndex: 0,
activeClick: 0
}
},
computed: {
// 左侧菜单栏
...mapGetters([
'leftMenu'
])
},
beforeDestroy() {
// 在组件销毁之前,解除滚动事件的监听器
this.$eventBus.$off('handleScroll', this.handleScroll)
},
mounted() {
// 右侧滚动事件
this.handleScroll = (val) => {
const rightContentElement = val.target // 获取右边总体容器元素
const scrollTop = rightContentElement.scrollTop
const a = this.$refs.home ? this.$refs.home.$refs : null
const sectionElements = {}
for (const key in a) {
sectionElements[key] = [a[key].$el]
}
// console.log('a: ', a, sectionElements)
let activeIndex = 0
let minDistance = Infinity
for (const key in sectionElements) {
if (key.startsWith('proRef')) {
const sectionElement = sectionElements[key][0]
const distance = Math.abs(sectionElement.offsetTop - scrollTop)
if (distance < minDistance) {
minDistance = distance
activeIndex = Number(key.split('proRef')[1])
this.activeClick = activeIndex
this.activeIndex = activeIndex
}
}
}
console.log(activeIndex)
}
this.$eventBus.$on('handleScroll', this.handleScroll)
},
methods: {
mouseover(index) {
this.activeIndex = index
},
mouseout() {
this.activeIndex = null
},
// 点击左侧菜单栏
changeHash(val, index) {
const el = this.$refs.home.$refs['proRef' + index].$attrs.id
// 获取对应的右侧内容的DOM元素
const section = document.getElementById(el)
// 将右侧内容滚动到可见区域
section.scrollIntoView({ behavior: 'smooth' })
// 更新当前活动的菜单项索引
this.activeClick = index
// this.isMenuScroll = true // 设置标志位为true,表示滚动由菜单点击触发
// 解除滚动事件的监听器
this.$eventBus.$off('handleScroll', this.handleScroll)
// 重新绑定滚动事件的监听器
setTimeout(() => {
this.$eventBus.$on('handleScroll', this.handleScroll)
}, 500)
}
}
}
</script>
<style lang="scss" scoped>
.content{
width: 100%;
display: flex;
height: 100%;
}
.left-menu{
width: 260px;
height: 100%;
ul{
margin: 0;
list-style-type: none;
width: 100%;
height: 100%;
background: #10183F;
border-radius: 0px 0px 0px 0px;
font-size: 14px;
font-family: Source Han Sans CN-Normal, Source Han Sans CN;
font-weight: 400;
color: rgba(255,255,255,0.8);
padding-top: 15px;
li{
height: 45px;
line-height: 45px;
cursor: pointer;
&:hover{
color: #50BE94;
}
img{
vertical-align: middle;
}
}
.active{
color: #50BE94;
}
}
}
</style>
// console.log('a: ', a, sectionElements)打印出来的内容
总体效果: