项目效果图:
项目描述:加载组建时,隐藏,鼠标滑动到指定区域的时候该菜单选中高亮,点击菜单跳转到指定模块,每个页面都适用。
html 部分:
提示:我这里有英文所以有$i18n.locale==='zh' 判断,使用的时候按照个人项目情况使用。
<div class="left-nav-box" ref="nav-box">
<div class="nav">
<div class="line">
<div class="sub-line active" :style="`margin-top: ${active*0.152}rem`"></div>
</div>
<ul>
<li v-for="(item,index) in menu"
:key="item.name" @click="tabClick(item,index)"
:style="`color:${active===index?'#fff':'rgba(255, 255, 255, 0.70)'}`"
>
{{ $i18n.locale === 'zh' ? item.title : item.titleEn }}
</li>
</ul>
</div>
</div>
css部分:
.left-nav-box {
position: fixed;
top: 220px;
left: 20px;
z-index: -1;
//display: none;
opacity: 0;
transition: 0.3s ease-in-out;
}
.line {
background: rgba(255, 255, 255, 0.26);
width: 4px;
border-radius: 4px 4px 4px 4px;
overflow: hidden;
.sub-line {
width: 4px;
height: 32px;
background: #1874F6;
border-radius: 4px;
}
}
.active {
transition: 0.3s ease-in-out;
}
.nav {
display: flex;
padding: 12px;
font-size: 15px;
min-width: 200px;
background: rgba(0, 0, 0, 0.26);
border-radius: 4px 4px 4px 4px;
opacity: 1;
border: 1px solid rgba(255, 255, 255, 0.3);
backdrop-filter: blur(25px);
ul {
width: 100%;
}
li {
width: 100%;
font-weight: 700;
color: rgba(255, 255, 255, 0.7);
display: block;
cursor: pointer;
&:hover {
color: #fff;
}
margin-bottom: 9px;
margin-left: 12px;
&:last-child {
margin-bottom: 0;
}
}
}
侧边栏json部分:
//注意:1: 数组的key名,需要根据组建的name来设置
// 2: 侧边菜单什么时候出现需要,在使用的组建中设置 id = 组建的name
// 3: 点击的链接需要在组建中设置 id= name.url(name:组建的name即home.url)
// 4: 需要在页面显示,设置菜单json数组就可以了
export default {
home:[
{url:'tab1',title:"xxxx",titleEn:"xxxx"},
{url:'tab2',title:"xxxx",titleEn:"xxxx"},
]
}
js部分:
import menu from "../LeftTabs/leftMenu"
export default {
name: "leftNav",
data() {
return {
menuLeft: menu,
active: 0,
num: 0,
top: []
}
},
props: {
menu: {
type: Array,
default: []
},
startMouse: {
type: String,
default: '#tab1'
}
},
mounted() {
this.getLoad();
},
watch: {
$route: {
handler: function () {
this.getLoad()
}
}
},
methods: {
getLoad() {
this.top = [];
if (this.menuLeft[this.$route.name]) {
this.menuLeft[this.$route.name].forEach((item, index) => {
this.num = index;
//获取每个侧边菜单距离顶部的距离
this.top[index] = document.getElementById(item.url).offsetTop;
})
window.addEventListener("scroll", this.scrollDown)
} else {
window.removeEventListener('scroll', this.scrollDown)
}
},
scrollDown() {
//获取从哪里开始显示侧边栏
let top = document.getElementById(this.startMouse);
if (top) {
let scrollTop =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop;
//获取菜单的每一项的小于鼠标滑动的距离顶部的高度
let item = this.top.filter(item => item < scrollTop);
// 排序取最大的一个
let numTxt = item.sort((a, b) => b - a)[0];
// 取最大的一个的索引
let index = this.top.findIndex(item => item === numTxt);
// 默认选中
this.active = isUndefined(numTxt) ? 0 : (numTxt < scrollTop ? index : this.num);
if (top.offsetTop < scrollTop) {
this.mouseShow();
} else {
this.mouseHide();
}
}
},
tabClick(item, index) {
this.active = index;
let tab = document.getElementById(item.url);
tab?.scrollIntoView();
},
mouseShow() {
let flag = this.$refs["nav-box"];
flag.style.opacity = '1';
flag.style.zIndex = '2004';
},
mouseHide() {
let flag = this.$refs["nav-box"];
flag.style.opacity = '0';
flag.style.zIndex = '-1';
}
}
}
应用:
提示:这里我是写在全局的layout里面,因为的的项目用的地方比较多。可根据自己的项目更改
import leftMenu from '@/components/LeftTabs/leftMenu'
<leftNav :menu="menuList"
:startMouse="start"
v-if="menuList!==''"
/>
export default {
data() {
return {
menuList:leftMenu[this.$route.name],
start:this.$route.name,
show: true
}
},
components: {
leftNav
},
mounted() {
this.getList();
},
watch: {
$route: {
handler: function () {
this.getList();
},
deep:true
},
},
methods:{
getList(){
this.menuList = leftMenu[this.$route.name] || "";
this.start = this.$route.name;
}
}
}
//id="home" 一定要组建的name
<div class="home-top" id="home">
</div>
//锚点滚动到指定位置,此id需要在json数组中的url定义的一致
<div class="home-tab1" id="tab1">
</div>
<div class="home-tab2" id="tab2">
</div>
总结:
好记性, 不如乱笔头,记个笔记。
第一:可能自己以后能用到
第二:可能帮助到有需要的人