- 作者:老汪软件技巧
- 发表时间:2024-09-15 11:01
- 浏览量:
一、效果点击导航可以跳转至对应的页面
页面滚动时高亮导航
二、实现点击导航可以跳转至对应的页面
handleNav(item) {
const ele = document.getElementById(item.component)
this.activeComp = item.component
ele.scrollIntoView({ behavior: 'smooth', block: 'start' })
},
页面滚动时高亮导航
// 初始化:设置每个标题的top值
init() {
this.$nextTick(() => {
const firstEle = this.componentList[0].component
const firstTop = document.getElementById(firstEle).offsetTop
this.componentList.forEach((item) => {
const ele = document.getElementById(item.component)
item.top = ele.offsetTop - firstTop
})
})
},
给滚动的dom元素添加事件: @scroll="handleScroll"
// 页面滚动,高亮nav
handleScroll(e) {
this.componentList.forEach((item) => {
if (item.top < e.target.scrollTop) {
this.activeComp = item.component
}
})
}
三、完整代码
<div class="product-add h-full pl-30 flex flex-col">
<el-steps :active="activeStep" finish-status="success" class="w-300 mx-auto my-20">
<el-step title="选择产品类型" />
<el-step title="填写产品详情" />
el-steps>
<div class="flex-1 overflow-y-auto flex flex-col">
<div class="flex-1 overflow-y-auto pr-120 pb-100" @scroll="handleScroll">
<div v-for="item of componentList" :key="item.component">
<h1 class="my-20 pl-8 text-16 border-l-4 border-solid border-green" :id="item.component">{{ item.title }}h1>
<component :is="item.component" ref="comRef" />
div>
div>
<ul class="nav-wrapper">
<li v-for="item of componentList" :key="item.component" @click="handleNav(item)" :class="item.component === activeComp && 'active'">
{{ item.title }}
li>
ul>
div>
div>
<script>
import BaseInfo from './components/BaseInfo' // 基本信息
import SpecInfo from './components/SpecInfo' // 规格信息
import ProductInfo from './components/ProductInfo' // 产品信息
import ProductPrice from './components/ProductPrice' // 产品计价
import PrintArea from './components/PrintArea' // 印刷区域维护
import PrintPrice from './components/PrintPrice' // 印刷计价
import { mapState, mapMutations, mapGetters } from 'vuex'
export default {
data() {
return {
activeStep: 1, // 0=选择产品类型 1=填写产品详情
componentList: [
{ title: '基本信息', component: 'BaseInfo' },
{ title: '规格信息', component: 'SpecInfo' },
{ title: '产品信息', component: 'ProductInfo' },
{ title: '产品计价', component: 'ProductPrice' },
{ title: '印刷区域维护', component: 'PrintArea' },
{ title: '印刷计价', component: 'PrintPrice' }
],
activeComp: 'BaseInfo' // 当前高亮的nav
}
},
computed: {
...mapState({ productAdd: (state) => state.productAdd })
},
watch: {
'productAdd.specInfo.tableData': {
handler() {
this.init()
},
deep: true,
immediate: true
}
},
methods: {
// 初始化:设置每个标题的top值
init() {
this.$nextTick(() => {
const firstEle = this.componentList[0].component
const firstTop = document.getElementById(firstEle).offsetTop
this.componentList.forEach((item) => {
const ele = document.getElementById(item.component)
item.top = ele.offsetTop - firstTop
})
})
},
// 点击导航栏滚动至对应的页面
handleNav(item) {
const ele = document.getElementById(item.component)
this.activeComp = item.component
ele.scrollIntoView({ behavior: 'smooth', block: 'start' })
},
// 页面滚动,高亮nav
handleScroll(e) {
this.componentList.forEach((item) => {
if (item.top < e.target.scrollTop) {
this.activeComp = item.component
}
})
}
},
components: { BaseInfo, SpecInfo, ProductInfo, ProductPrice, PrintArea, PrintPrice }
}
script>
<style lang="scss" scoped>
@import './index.scss';
style>
css:
.nav-wrapper {
position: fixed;
right: 26px;
top: 50%;
transform: translateY(-50%);
z-index: 100;
li {
font-size: 14px;
text-align: right;
line-height: 24px;
cursor: pointer;
color: #555;
&.active {
color: #009944;
}
}
}
注意点:
当手动添加或减少规格值时,需要重新执行init函数,获取到最新的top值,如果你的页面是固定的,那么只需要初始化时执行一遍init即可在获取top值时,需要减去第一个title的offsetTop,如果你的页面的title前面没有元素,那么可以不用减