|
|
@ -1,15 +1,17 @@ |
|
|
|
<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)"> |
|
|
|
<SvgIcon1 :iconPath="require(`@/assets/${item.img}`)" defaultColor="#8A9099" :size="16" |
|
|
|
activeColor="#006AFF" :isActive="$route.path == item.path" /> |
|
|
|
<span class="title_text" >{{ item.name }}</span> |
|
|
|
<li v-for="(item, index) in menuList" :key="item.path + random()"> |
|
|
|
<div |
|
|
|
:class="[($route.path == item.path) || (item.noToPath && curIndex == index) ? 'active' : '', 'flex', ($route.path == item.path) ? curIndex = index : '']" |
|
|
|
> |
|
|
|
<!-- @click="gotoPath(item, index)" 暂时先注释 --> |
|
|
|
<SvgIcon1 :iconPath="require(`@/assets/${item.img}`)" defaultColor="#8A9099" :size="16" activeColor="#006AFF" |
|
|
|
:isActive="($route.path == item.path || (item.noToPath && curIndex == index))" /> |
|
|
|
<span class="title_text">{{ item.name }}</span> |
|
|
|
</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> |
|
|
|
<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> |
|
|
@ -17,7 +19,6 @@ |
|
|
|
|
|
|
|
<script> |
|
|
|
import SvgIcon1 from '@/components/SvgIcon1.vue'; |
|
|
|
// :class="[$route.path != item.path ? 'not-point' : '', 'flex', activeFloor == item1.desc ? 'curActive' : '']" |
|
|
|
import { mapState } from 'vuex'; |
|
|
|
import store from '../store'; |
|
|
|
export default { |
|
|
@ -42,149 +43,116 @@ export default { |
|
|
|
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(); |
|
|
|
|
|
|
|
watch: { |
|
|
|
'$route'(to, from) { |
|
|
|
console.log(to, from); |
|
|
|
// 路由变化时重新计算位置 |
|
|
|
this.$nextTick(() => { |
|
|
|
// console.log(this.$parent.$refs.scrollContainer, 'this.$refs.scrollContainer--'); |
|
|
|
this.$parent.$refs.scrollContainer.addEventListener('scroll', this.handleScroll); |
|
|
|
}) |
|
|
|
}, |
|
|
|
this.calculateFloorOffsets(); |
|
|
|
this.handleScroll(); // 立即检查当前位置 |
|
|
|
}); |
|
|
|
} |
|
|
|
}, |
|
|
|
mounted() { |
|
|
|
this.activeFloor = this.menuList[this.curIndex]?.list?.[0]?.desc; |
|
|
|
this.$nextTick(() => { |
|
|
|
// 更可靠的获取滚动容器方式 |
|
|
|
this.scrollContainer = document.querySelector('.main-content') || |
|
|
|
document.getElementById('main-content') || |
|
|
|
window; |
|
|
|
|
|
|
|
if (this.scrollContainer) { |
|
|
|
this.scrollContainer.addEventListener('scroll', this.handleScroll); |
|
|
|
this.calculateFloorOffsets(); |
|
|
|
} else { |
|
|
|
console.error('未找到滚动容器'); |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
beforeDestroy() { |
|
|
|
if (this.scrollContainer) { |
|
|
|
this.scrollContainer.removeEventListener('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); |
|
|
|
...mapState(['pageTitle']) // 从Vuex映射showSidebar状态到组件的计算属性中 |
|
|
|
}, |
|
|
|
methods: { |
|
|
|
calculateFloorOffsets() { |
|
|
|
this.menuList.forEach(item => { |
|
|
|
item.list.forEach(every => { |
|
|
|
const el = document.getElementById(every.desc); |
|
|
|
if (el) { |
|
|
|
every.offsetTop = el.offsetTop; |
|
|
|
} |
|
|
|
}) |
|
|
|
}); |
|
|
|
random() { |
|
|
|
var randomNumber = Math.random(); |
|
|
|
return randomNumber |
|
|
|
}, |
|
|
|
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; // 一旦找到第一个小于当前滚动位置的楼层,停止循环 |
|
|
|
calculateFloorOffsets() { |
|
|
|
this.menuList.forEach(item => { |
|
|
|
item.list?.forEach(every => { |
|
|
|
const el = document.getElementById(every.desc); |
|
|
|
if (el) { |
|
|
|
// 获取元素相对于视口顶部的距离 |
|
|
|
every.offsetTop = el.getBoundingClientRect().top + window.pageYOffset; |
|
|
|
} |
|
|
|
}); |
|
|
|
this.activeFloor = activeFloor; // 更新数据以触发视图更新 |
|
|
|
}, |
|
|
|
setActiveCur(dom,item) { |
|
|
|
if(this.$route.path != item.path){ |
|
|
|
this.$router.push(item.path) |
|
|
|
store.commit('SET_PAGETITLE', item.name); |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
handleScroll() { |
|
|
|
if (this.scrollLock || !this.menuList[this.curIndex]?.list) return; |
|
|
|
|
|
|
|
const scrollPosition = this.getScrollPosition(); |
|
|
|
let activeFloor = null; |
|
|
|
|
|
|
|
// 从下往上查找当前可见区域对应的楼层 |
|
|
|
for (let i = this.menuList[this.curIndex].list.length - 1; i >= 0; i--) { |
|
|
|
const item = this.menuList[this.curIndex].list[i]; |
|
|
|
if (scrollPosition + 100 >= (item.offsetTop || 0)) { // 100是提前量 |
|
|
|
activeFloor = item.desc; |
|
|
|
break; |
|
|
|
} |
|
|
|
setTimeout(()=>{ |
|
|
|
this.activeFloor = dom; |
|
|
|
this.setHighActive(dom) |
|
|
|
},500) |
|
|
|
}, |
|
|
|
gotoPath(path,index) { |
|
|
|
if(this.$route.path != path){ |
|
|
|
} |
|
|
|
|
|
|
|
if (activeFloor && this.activeFloor !== activeFloor) { |
|
|
|
this.activeFloor = activeFloor; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
getScrollPosition() { |
|
|
|
if (this.scrollContainer === window) { |
|
|
|
return window.pageYOffset || document.documentElement.scrollTop; |
|
|
|
} |
|
|
|
return this.scrollContainer.scrollTop; |
|
|
|
}, |
|
|
|
// 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) |
|
|
|
// }, |
|
|
|
|
|
|
|
// 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) |
|
|
|
// } |
|
|
|
gotoPath(item, index) { |
|
|
|
let path = item.path; |
|
|
|
if (!path) { |
|
|
|
this.curIndex = index; |
|
|
|
return |
|
|
|
} |
|
|
|
if (this.$route.path != path) { |
|
|
|
this.curIndex = index |
|
|
|
this.scrollLock = false; |
|
|
|
this.handleScroll() |
|
|
@ -197,23 +165,39 @@ export default { |
|
|
|
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) |
|
|
|
} |
|
|
|
setActiveCur(dom, item) { |
|
|
|
if (this.$route.path !== item.path) { |
|
|
|
this.$router.push(item.path); |
|
|
|
store.commit('SET_PAGETITLE', item.name); |
|
|
|
} |
|
|
|
|
|
|
|
this.scrollLock = true; |
|
|
|
this.activeFloor = dom; |
|
|
|
|
|
|
|
this.$nextTick(() => { |
|
|
|
this.setHighActive(dom); |
|
|
|
setTimeout(() => { |
|
|
|
this.scrollLock = false; |
|
|
|
}, 1000); |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
setHighActive(dom) { |
|
|
|
const ele = document.getElementById(dom); |
|
|
|
if (ele) { |
|
|
|
ele.scrollIntoView({ |
|
|
|
behavior: 'smooth', |
|
|
|
block: 'start' |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
</script> |
|
|
|
|
|
|
|
<style scoped lang="scss"> |
|
|
|
.sidebar { |
|
|
|
width: 158px; |
|
|
|
min-width: 158px; |
|
|
|
padding: 21px; |
|
|
|
box-sizing: border-box; |
|
|
|
background: #FFFFFF; |
|
|
@ -223,7 +207,8 @@ export default { |
|
|
|
.ceshi { |
|
|
|
// animation: fadeInOut 2s infinite; |
|
|
|
} |
|
|
|
.title_text{ |
|
|
|
|
|
|
|
.title_text { |
|
|
|
margin-left: 6px; |
|
|
|
} |
|
|
|
|
|
|
|