<template> <aside class="sidebar"> <ul> <li v-for="(item, index) in menuList" :key="item.path"> <div :class="[$route.path == item.path ? 'active' : '', 'flex', $route.path == item.path ? curIndex = index : '']" @click="gotoPath(item.path,index)"> <img v-if="$route.path == item.path" :src="item.imgActive" alt=""> <img v-else :src="item.img" alt=""> {{ item.name }} </div> <p :class="['flex', activeFloor == item1.desc ? 'curActive' : '']" v-for="(item1) in item.list" @click="setActiveCur(item1.desc,item)" :key="item1.name">{{ item1.name }}</p> </li> </ul> </aside> </template> <script> // :class="[$route.path != item.path ? 'not-point' : '', 'flex', activeFloor == item1.desc ? 'curActive' : '']" import { mapState } from 'vuex'; import store from '../store'; export default { name: 'Sidebar', props: { // menuList: { // type: Array, // required: true // }, // activeFloor:{ // type:String // }, // curIndex:{ // type:Number // } }, data() { return { activeFloor: null, curIndex: 0, scrollLock: false, menuList: [ { name: '基本设置', path: '/siteSetting/siteBaseSetting', img: require('@/assets/site/sitebase.svg'), imgActive: require('@/assets/site/sitebase_active.svg'), list: [ { name: '站点信息', desc: 'siteMessage1' }, { name: '域名设置', desc: 'siteMessage2' }, { name: '收款方式', desc: 'siteMessage3' }, ] }, { name: '个性化设置', path: '/siteSetting/sitePersonalization', img: require('@/assets/site/gexinghua.svg'), imgActive: require('@/assets/site/sitebase_active.svg'), list: [ { name: '网页模板', desc: 'siteMessage4' }, { name: '客服设置', desc: 'siteMessage5' }, { name: '功能显隐', desc: 'siteMessage6' }, { name: '安全提交', desc: 'siteMessage7' }, { name: '初始订单数', desc: 'siteMessage8' }, ] }, { name: '移动端设置', path: '/siteSetting/siteH5', img: require('@/assets/site/siteh5.svg'), imgActive: require('@/assets/site/sitebase_active.svg'), list: [ { name: '微信H5', desc: 'siteMessage9' }, { name: '小程序', desc: 'siteMessage10' }, ] }, { name: '营销推广', path: '/siteSetting/siteSem', img: require('@/assets/site/sitesem.svg'), imgActive: require('@/assets/site/sitebase_active.svg'), list: [ { name: 'SEO设置', desc: 'siteMessage11' }, { name: 'SEM设置', desc: 'siteMessage12' }, { name: '访问统计', desc: 'siteMessage13' }, ] } ] } }, mounted() { // console.log(this.curIndex,'this.curIndex'); this.activeFloor = this.menuList[this.curIndex]['list'][0]['desc']; this.calculateFloorOffsets(); this.$nextTick(() => { // console.log(this.$parent.$refs.scrollContainer, 'this.$refs.scrollContainer--'); }) this.$parent.$refs.scrollContainer.addEventListener('scroll', this.handleScroll); }, created() { // console.log(this.$parent.$refs.scrollContainer,'this.$refs.sc--rollContainer--'); }, computed: { ...mapState(['pageTitle']) // 从Vuex映射showSidebar状态到组件的计算属性中 }, beforeDestroy() { this.$parent.$refs.scrollContainer.removeEventListener('scroll', this.handleScroll); }, methods: { calculateFloorOffsets() { this.menuList.forEach(item => { item.list.forEach(every => { const el = document.getElementById(every.desc); if (el) { every.offsetTop = el.offsetTop; } }) }); }, handleScroll() { if (this.scrollLock) return const scrollContainer = this.$parent.$refs.scrollContainer; const scrollHeight = scrollContainer.scrollTop; let activeFloor = this.menuList[this.curIndex]['list'][0]['desc']; this.menuList[this.curIndex]['list'].forEach(item => { if (scrollHeight + 72 >= item.offsetTop) { activeFloor = item.desc; // 更新当前激活的楼层ID } else { return false; // 一旦找到第一个小于当前滚动位置的楼层,停止循环 } }); this.activeFloor = activeFloor; // 更新数据以触发视图更新 }, setActiveCur(dom,item) { if(this.$route.path != item.path){ this.$router.push(item.path) store.commit('SET_PAGETITLE', item.name); } setTimeout(()=>{ this.activeFloor = dom; this.setHighActive(dom) },500) }, gotoPath(path,index) { if(this.$route.path != path){ this.curIndex = index this.scrollLock = false; this.handleScroll() // 重置页面滚动高度 const dom = document.getElementById('main-content') dom.scrollTop = 0 this.$router.push(path) } }, activeArea(type) { console.log(type); }, setHighActive(dom) { this.scrollLock = true; const ele = document.getElementById(dom) if(!ele)return ele.classList.add('ceshi') ele.scrollIntoView({ behavior: 'smooth', block: 'start' }) setTimeout(() => { ele.classList.remove('ceshi') }, 1000) } } } </script> <style scoped lang="scss"> .sidebar { width: 158px; padding: 21px; box-sizing: border-box; background: #FFFFFF; box-shadow: 0px 0px 11px 2px rgba(147, 147, 147, 0.11); } .ceshi { // animation: fadeInOut 2s infinite; } ul { list-style: none; padding: 0; } .not-point { pointer-events: none; /* 阻止鼠标事件 */ opacity: 0.5; /* 可选,降低透明度以视觉上表示不可用 */ cursor: not-allowed; /* 改变鼠标光标样式,表示不可用 */ } li { margin-bottom: 10px; div { letter-spacing: 0.08em; color: #1E2226; margin: 11px 0; cursor: pointer; img { margin-right: 6px; } } p { margin: 9px 0; letter-spacing: 0.08em; line-height: 18px; color: #8A9099; cursor: pointer; &:hover { color: #006AFF; } } .curActive { color: #006AFF; } } /* { display: block; padding: 8px 12px; text-decoration: none; color: #333; border-radius: 4px; } */ /* :hover { background: #e0e0e0; } */ .active { font-weight: bold; letter-spacing: 0.08em; color: #006AFF; } .item-active { color: #006AFF; } /* .exact-active { background: #1976d2; color: white; } */ </style>